Nullability fine-tuning around bean properties
Issue: SPR-15720 Issue: SPR-15792
This commit is contained in:
@@ -126,7 +126,7 @@ public class FieldRetrievingFactoryBean
|
|||||||
* @see #setTargetObject
|
* @see #setTargetObject
|
||||||
*/
|
*/
|
||||||
public void setTargetField(@Nullable String targetField) {
|
public void setTargetField(@Nullable String targetField) {
|
||||||
this.targetField = StringUtils.trimAllWhitespace(targetField);
|
this.targetField = (targetField != null ? StringUtils.trimAllWhitespace(targetField) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -81,8 +81,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
|||||||
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private final Map<CacheOperationCacheKey, CacheOperationMetadata> metadataCache =
|
private final Map<CacheOperationCacheKey, CacheOperationMetadata> metadataCache = new ConcurrentHashMap<>(1024);
|
||||||
new ConcurrentHashMap<>(1024);
|
|
||||||
|
|
||||||
private final CacheOperationExpressionEvaluator evaluator = new CacheOperationExpressionEvaluator();
|
private final CacheOperationExpressionEvaluator evaluator = new CacheOperationExpressionEvaluator();
|
||||||
|
|
||||||
@@ -186,6 +185,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
|||||||
public void afterSingletonsInstantiated() {
|
public void afterSingletonsInstantiated() {
|
||||||
if (getCacheResolver() == null) {
|
if (getCacheResolver() == null) {
|
||||||
// Lazily initialize cache resolver via default cache manager...
|
// Lazily initialize cache resolver via default cache manager...
|
||||||
|
Assert.state(this.beanFactory != null, "CacheResolver or BeanFactory must be set on cache aspect");
|
||||||
try {
|
try {
|
||||||
setCacheManager(this.beanFactory.getBean(CacheManager.class));
|
setCacheManager(this.beanFactory.getBean(CacheManager.class));
|
||||||
}
|
}
|
||||||
@@ -289,6 +289,10 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
|||||||
* @see CacheOperation#cacheResolver
|
* @see CacheOperation#cacheResolver
|
||||||
*/
|
*/
|
||||||
protected <T> T getBean(String beanName, Class<T> expectedType) {
|
protected <T> T getBean(String beanName, Class<T> expectedType) {
|
||||||
|
if (this.beanFactory == null) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"BeanFactory must be set on cache aspect for " + expectedType.getSimpleName() + " retrieval");
|
||||||
|
}
|
||||||
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(this.beanFactory, expectedType, beanName);
|
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(this.beanFactory, expectedType, beanName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -38,6 +38,7 @@ public abstract class AbstractResourceBasedMessageSource extends AbstractMessage
|
|||||||
|
|
||||||
private final Set<String> basenameSet = new LinkedHashSet<>(4);
|
private final Set<String> basenameSet = new LinkedHashSet<>(4);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private String defaultEncoding;
|
private String defaultEncoding;
|
||||||
|
|
||||||
private boolean fallbackToSystemLocale = true;
|
private boolean fallbackToSystemLocale = true;
|
||||||
|
|||||||
@@ -535,9 +535,6 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void assertValidators(Validator... validators) {
|
private void assertValidators(Validator... validators) {
|
||||||
if (validators == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (Validator validator : validators) {
|
for (Validator validator : validators) {
|
||||||
if (validator != null && (getTarget() != null && !validator.supports(getTarget().getClass()))) {
|
if (validator != null && (getTarget() != null && !validator.supports(getTarget().getClass()))) {
|
||||||
throw new IllegalStateException("Invalid target for Validator [" + validator + "]: " + getTarget());
|
throw new IllegalStateException("Invalid target for Validator [" + validator + "]: " + getTarget());
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ public class CustomizableThreadCreator implements Serializable {
|
|||||||
|
|
||||||
private boolean daemon = false;
|
private boolean daemon = false;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private ThreadGroup threadGroup;
|
private ThreadGroup threadGroup;
|
||||||
|
|
||||||
private final AtomicInteger threadCount = new AtomicInteger(0);
|
private final AtomicInteger threadCount = new AtomicInteger(0);
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ public class ListenableFutureCallbackRegistry<T> {
|
|||||||
* added callbacks with the given result.
|
* added callbacks with the given result.
|
||||||
* @param result the result to trigger the callbacks with
|
* @param result the result to trigger the callbacks with
|
||||||
*/
|
*/
|
||||||
public void success(T result) {
|
public void success(@Nullable T result) {
|
||||||
synchronized (this.mutex) {
|
synchronized (this.mutex) {
|
||||||
this.state = State.SUCCESS;
|
this.state = State.SUCCESS;
|
||||||
this.result = result;
|
this.result = result;
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ abstract class AbstractXMLReader implements XMLReader {
|
|||||||
* handler. The property name for a lexical handler is {@code http://xml.org/sax/properties/lexical-handler}.
|
* handler. The property name for a lexical handler is {@code http://xml.org/sax/properties/lexical-handler}.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
|
public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||||
if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
|
if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
|
||||||
return this.lexicalHandler;
|
return this.lexicalHandler;
|
||||||
|
|||||||
@@ -244,6 +244,19 @@ public class CallMetaDataContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize this class with metadata from the database.
|
||||||
|
* @param dataSource the DataSource used to retrieve metadata
|
||||||
|
*/
|
||||||
|
public void initializeMetaData(DataSource dataSource) {
|
||||||
|
this.metaDataProvider = CallMetaDataProviderFactory.createMetaDataProvider(dataSource, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CallMetaDataProvider obtainMetaDataProvider() {
|
||||||
|
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider - call initializeMetaData first");
|
||||||
|
return this.metaDataProvider;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a ReturnResultSetParameter/SqlOutParameter depending on the support provided
|
* Create a ReturnResultSetParameter/SqlOutParameter depending on the support provided
|
||||||
* by the JDBC driver used for the database in use.
|
* by the JDBC driver used for the database in use.
|
||||||
@@ -252,13 +265,13 @@ public class CallMetaDataContext {
|
|||||||
* @return the appropriate SqlParameter
|
* @return the appropriate SqlParameter
|
||||||
*/
|
*/
|
||||||
public SqlParameter createReturnResultSetParameter(String parameterName, RowMapper<?> rowMapper) {
|
public SqlParameter createReturnResultSetParameter(String parameterName, RowMapper<?> rowMapper) {
|
||||||
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
|
CallMetaDataProvider provider = obtainMetaDataProvider();
|
||||||
if (this.metaDataProvider.isReturnResultSetSupported()) {
|
if (provider.isReturnResultSetSupported()) {
|
||||||
return new SqlReturnResultSet(parameterName, rowMapper);
|
return new SqlReturnResultSet(parameterName, rowMapper);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (this.metaDataProvider.isRefCursorSupported()) {
|
if (provider.isRefCursorSupported()) {
|
||||||
return new SqlOutParameter(parameterName, this.metaDataProvider.getRefCursorSqlType(), rowMapper);
|
return new SqlOutParameter(parameterName, provider.getRefCursorSqlType(), rowMapper);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new InvalidDataAccessApiUsageException("Return of a ResultSet from a stored procedure is not supported.");
|
throw new InvalidDataAccessApiUsageException("Return of a ResultSet from a stored procedure is not supported.");
|
||||||
@@ -290,14 +303,6 @@ public class CallMetaDataContext {
|
|||||||
return this.callParameters;
|
return this.callParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize this class with metadata from the database.
|
|
||||||
* @param dataSource the DataSource used to retrieve metadata
|
|
||||||
*/
|
|
||||||
public void initializeMetaData(DataSource dataSource) {
|
|
||||||
this.metaDataProvider = CallMetaDataProviderFactory.createMetaDataProvider(dataSource, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the list of parameters provided, and if procedure column metadata is used,
|
* Process the list of parameters provided, and if procedure column metadata is used,
|
||||||
* the parameters will be matched against the metadata information and any missing
|
* the parameters will be matched against the metadata information and any missing
|
||||||
@@ -312,7 +317,7 @@ public class CallMetaDataContext {
|
|||||||
* Reconcile the provided parameters with available metadata and add new ones where appropriate.
|
* Reconcile the provided parameters with available metadata and add new ones where appropriate.
|
||||||
*/
|
*/
|
||||||
protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters) {
|
protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters) {
|
||||||
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
|
CallMetaDataProvider provider = obtainMetaDataProvider();
|
||||||
|
|
||||||
final List<SqlParameter> declaredReturnParams = new ArrayList<>();
|
final List<SqlParameter> declaredReturnParams = new ArrayList<>();
|
||||||
final Map<String, SqlParameter> declaredParams = new LinkedHashMap<>();
|
final Map<String, SqlParameter> declaredParams = new LinkedHashMap<>();
|
||||||
@@ -321,7 +326,7 @@ public class CallMetaDataContext {
|
|||||||
List<String> metaDataParamNames = new ArrayList<>();
|
List<String> metaDataParamNames = new ArrayList<>();
|
||||||
|
|
||||||
// Get the names of the meta data parameters
|
// Get the names of the meta data parameters
|
||||||
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
|
for (CallParameterMetaData meta : provider.getCallParameterMetaData()) {
|
||||||
if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) {
|
if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) {
|
||||||
metaDataParamNames.add(lowerCase(meta.getParameterName()));
|
metaDataParamNames.add(lowerCase(meta.getParameterName()));
|
||||||
}
|
}
|
||||||
@@ -338,7 +343,7 @@ public class CallMetaDataContext {
|
|||||||
throw new IllegalArgumentException("Anonymous parameters not supported for calls - " +
|
throw new IllegalArgumentException("Anonymous parameters not supported for calls - " +
|
||||||
"please specify a name for the parameter of SQL type " + param.getSqlType());
|
"please specify a name for the parameter of SQL type " + param.getSqlType());
|
||||||
}
|
}
|
||||||
String paramNameToMatch = lowerCase(this.metaDataProvider.parameterNameToUse(paramName));
|
String paramNameToMatch = lowerCase(provider.parameterNameToUse(paramName));
|
||||||
declaredParams.put(paramNameToMatch, param);
|
declaredParams.put(paramNameToMatch, param);
|
||||||
if (param instanceof SqlOutParameter) {
|
if (param instanceof SqlOutParameter) {
|
||||||
outParamNames.add(paramName);
|
outParamNames.add(paramName);
|
||||||
@@ -360,24 +365,23 @@ public class CallMetaDataContext {
|
|||||||
List<SqlParameter> workParams = new ArrayList<>();
|
List<SqlParameter> workParams = new ArrayList<>();
|
||||||
workParams.addAll(declaredReturnParams);
|
workParams.addAll(declaredReturnParams);
|
||||||
|
|
||||||
if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
|
if (!provider.isProcedureColumnMetaDataUsed()) {
|
||||||
workParams.addAll(declaredParams.values());
|
workParams.addAll(declaredParams.values());
|
||||||
return workParams;
|
return workParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> limitedInParamNamesMap = new HashMap<>(this.limitedInParameterNames.size());
|
Map<String, String> limitedInParamNamesMap = new HashMap<>(this.limitedInParameterNames.size());
|
||||||
for (String limitedParamName : this.limitedInParameterNames) {
|
for (String limitedParamName : this.limitedInParameterNames) {
|
||||||
limitedInParamNamesMap.put(
|
limitedInParamNamesMap.put(lowerCase(provider.parameterNameToUse(limitedParamName)), limitedParamName);
|
||||||
lowerCase(this.metaDataProvider.parameterNameToUse(limitedParamName)), limitedParamName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
|
for (CallParameterMetaData meta : provider.getCallParameterMetaData()) {
|
||||||
String paramName = meta.getParameterName();
|
String paramName = meta.getParameterName();
|
||||||
String paramNameToCheck = null;
|
String paramNameToCheck = null;
|
||||||
if (paramName != null) {
|
if (paramName != null) {
|
||||||
paramNameToCheck = lowerCase(this.metaDataProvider.parameterNameToUse(paramName));
|
paramNameToCheck = lowerCase(provider.parameterNameToUse(paramName));
|
||||||
}
|
}
|
||||||
String paramNameToUse = this.metaDataProvider.parameterNameToUse(paramName);
|
String paramNameToUse = provider.parameterNameToUse(paramName);
|
||||||
if (declaredParams.containsKey(paramNameToCheck) ||
|
if (declaredParams.containsKey(paramNameToCheck) ||
|
||||||
(meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) {
|
(meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) {
|
||||||
SqlParameter param;
|
SqlParameter param;
|
||||||
@@ -409,7 +413,7 @@ public class CallMetaDataContext {
|
|||||||
else {
|
else {
|
||||||
if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) {
|
if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) {
|
||||||
if (!isFunction() && !isReturnValueRequired() && paramName != null &&
|
if (!isFunction() && !isReturnValueRequired() && paramName != null &&
|
||||||
this.metaDataProvider.byPassReturnParameter(paramName)) {
|
provider.byPassReturnParameter(paramName)) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Bypassing metadata return parameter for '" + paramName + "'");
|
logger.debug("Bypassing metadata return parameter for '" + paramName + "'");
|
||||||
}
|
}
|
||||||
@@ -417,7 +421,7 @@ public class CallMetaDataContext {
|
|||||||
else {
|
else {
|
||||||
String returnNameToUse =
|
String returnNameToUse =
|
||||||
(StringUtils.hasLength(paramNameToUse) ? paramNameToUse : getFunctionReturnName());
|
(StringUtils.hasLength(paramNameToUse) ? paramNameToUse : getFunctionReturnName());
|
||||||
workParams.add(this.metaDataProvider.createDefaultOutParameter(returnNameToUse, meta));
|
workParams.add(provider.createDefaultOutParameter(returnNameToUse, meta));
|
||||||
if (isFunction()) {
|
if (isFunction()) {
|
||||||
setFunctionReturnName(returnNameToUse);
|
setFunctionReturnName(returnNameToUse);
|
||||||
outParamNames.add(returnNameToUse);
|
outParamNames.add(returnNameToUse);
|
||||||
@@ -432,14 +436,14 @@ public class CallMetaDataContext {
|
|||||||
paramNameToUse = "";
|
paramNameToUse = "";
|
||||||
}
|
}
|
||||||
if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) {
|
if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) {
|
||||||
workParams.add(this.metaDataProvider.createDefaultOutParameter(paramNameToUse, meta));
|
workParams.add(provider.createDefaultOutParameter(paramNameToUse, meta));
|
||||||
outParamNames.add(paramNameToUse);
|
outParamNames.add(paramNameToUse);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Added metadata out parameter for '" + paramNameToUse + "'");
|
logger.debug("Added metadata out parameter for '" + paramNameToUse + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) {
|
else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) {
|
||||||
workParams.add(this.metaDataProvider.createDefaultInOutParameter(paramNameToUse, meta));
|
workParams.add(provider.createDefaultInOutParameter(paramNameToUse, meta));
|
||||||
outParamNames.add(paramNameToUse);
|
outParamNames.add(paramNameToUse);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Added metadata in out parameter for '" + paramNameToUse + "'");
|
logger.debug("Added metadata in out parameter for '" + paramNameToUse + "'");
|
||||||
@@ -448,7 +452,7 @@ public class CallMetaDataContext {
|
|||||||
else {
|
else {
|
||||||
if (this.limitedInParameterNames.isEmpty() ||
|
if (this.limitedInParameterNames.isEmpty() ||
|
||||||
limitedInParamNamesMap.containsKey(lowerCase(paramNameToUse))) {
|
limitedInParamNamesMap.containsKey(lowerCase(paramNameToUse))) {
|
||||||
workParams.add(this.metaDataProvider.createDefaultInParameter(paramNameToUse, meta));
|
workParams.add(provider.createDefaultInParameter(paramNameToUse, meta));
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Added metadata in parameter for '" + paramNameToUse + "'");
|
logger.debug("Added metadata in parameter for '" + paramNameToUse + "'");
|
||||||
}
|
}
|
||||||
@@ -473,8 +477,6 @@ public class CallMetaDataContext {
|
|||||||
* @return a Map containing the matched parameter names with the value taken from the input
|
* @return a Map containing the matched parameter names with the value taken from the input
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameterSource parameterSource) {
|
public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameterSource parameterSource) {
|
||||||
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
|
|
||||||
|
|
||||||
// For parameter source lookups we need to provide case-insensitive lookup support
|
// For parameter source lookups we need to provide case-insensitive lookup support
|
||||||
// since the database metadata is not necessarily providing case sensitive parameter names.
|
// since the database metadata is not necessarily providing case sensitive parameter names.
|
||||||
Map<String, String> caseInsensitiveParameterNames =
|
Map<String, String> caseInsensitiveParameterNames =
|
||||||
@@ -485,7 +487,7 @@ public class CallMetaDataContext {
|
|||||||
for (SqlParameter parameter : this.callParameters) {
|
for (SqlParameter parameter : this.callParameters) {
|
||||||
if (parameter.isInputValueProvided()) {
|
if (parameter.isInputValueProvided()) {
|
||||||
String parameterName = parameter.getName();
|
String parameterName = parameter.getName();
|
||||||
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
|
String parameterNameToMatch = obtainMetaDataProvider().parameterNameToUse(parameterName);
|
||||||
if (parameterNameToMatch != null) {
|
if (parameterNameToMatch != null) {
|
||||||
callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName);
|
callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName);
|
||||||
}
|
}
|
||||||
@@ -538,8 +540,8 @@ public class CallMetaDataContext {
|
|||||||
* @return a Map containing the matched parameter names with the value taken from the input
|
* @return a Map containing the matched parameter names with the value taken from the input
|
||||||
*/
|
*/
|
||||||
public Map<String, ?> matchInParameterValuesWithCallParameters(Map<String, ?> inParameters) {
|
public Map<String, ?> matchInParameterValuesWithCallParameters(Map<String, ?> inParameters) {
|
||||||
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
|
CallMetaDataProvider provider = obtainMetaDataProvider();
|
||||||
if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
|
if (!provider.isProcedureColumnMetaDataUsed()) {
|
||||||
return inParameters;
|
return inParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,7 +549,7 @@ public class CallMetaDataContext {
|
|||||||
for (SqlParameter parameter : this.callParameters) {
|
for (SqlParameter parameter : this.callParameters) {
|
||||||
if (parameter.isInputValueProvided()) {
|
if (parameter.isInputValueProvided()) {
|
||||||
String parameterName = parameter.getName();
|
String parameterName = parameter.getName();
|
||||||
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
|
String parameterNameToMatch = provider.parameterNameToUse(parameterName);
|
||||||
if (parameterNameToMatch != null) {
|
if (parameterNameToMatch != null) {
|
||||||
callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName);
|
callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName);
|
||||||
}
|
}
|
||||||
@@ -556,7 +558,7 @@ public class CallMetaDataContext {
|
|||||||
|
|
||||||
Map<String, Object> matchedParameters = new HashMap<>(inParameters.size());
|
Map<String, Object> matchedParameters = new HashMap<>(inParameters.size());
|
||||||
for (String parameterName : inParameters.keySet()) {
|
for (String parameterName : inParameters.keySet()) {
|
||||||
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
|
String parameterNameToMatch = provider.parameterNameToUse(parameterName);
|
||||||
String callParameterName = callParameterNames.get(lowerCase(parameterNameToMatch));
|
String callParameterName = callParameterNames.get(lowerCase(parameterNameToMatch));
|
||||||
if (callParameterName == null) {
|
if (callParameterName == null) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
@@ -577,7 +579,7 @@ public class CallMetaDataContext {
|
|||||||
|
|
||||||
if (matchedParameters.size() < callParameterNames.size()) {
|
if (matchedParameters.size() < callParameterNames.size()) {
|
||||||
for (String parameterName : callParameterNames.keySet()) {
|
for (String parameterName : callParameterNames.keySet()) {
|
||||||
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
|
String parameterNameToMatch = provider.parameterNameToUse(parameterName);
|
||||||
String callParameterName = callParameterNames.get(lowerCase(parameterNameToMatch));
|
String callParameterName = callParameterNames.get(lowerCase(parameterNameToMatch));
|
||||||
if (!matchedParameters.containsKey(callParameterName)) {
|
if (!matchedParameters.containsKey(callParameterName)) {
|
||||||
logger.warn("Unable to locate the corresponding parameter value for '" + parameterName +
|
logger.warn("Unable to locate the corresponding parameter value for '" + parameterName +
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
|||||||
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
|
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
|
||||||
import org.springframework.jdbc.support.JdbcUtils;
|
import org.springframework.jdbc.support.JdbcUtils;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to manage context metadata used for the configuration
|
* Class to manage context metadata used for the configuration
|
||||||
@@ -47,13 +48,16 @@ public class TableMetaDataContext {
|
|||||||
/** Logger available to subclasses */
|
/** Logger available to subclasses */
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
/** name of table for this context **/
|
/** Name of table for this context */
|
||||||
|
@Nullable
|
||||||
private String tableName;
|
private String tableName;
|
||||||
|
|
||||||
/** name of catalog for this context **/
|
/** Name of catalog for this context */
|
||||||
|
@Nullable
|
||||||
private String catalogName;
|
private String catalogName;
|
||||||
|
|
||||||
/** name of schema for this context **/
|
/** Name of schema for this context */
|
||||||
|
@Nullable
|
||||||
private String schemaName;
|
private String schemaName;
|
||||||
|
|
||||||
/** List of columns objects to be used in this context */
|
/** List of columns objects to be used in this context */
|
||||||
@@ -66,6 +70,7 @@ public class TableMetaDataContext {
|
|||||||
private boolean overrideIncludeSynonymsDefault = false;
|
private boolean overrideIncludeSynonymsDefault = false;
|
||||||
|
|
||||||
/** the provider of table meta data */
|
/** the provider of table meta data */
|
||||||
|
@Nullable
|
||||||
private TableMetaDataProvider metaDataProvider;
|
private TableMetaDataProvider metaDataProvider;
|
||||||
|
|
||||||
/** are we using generated key columns */
|
/** are we using generated key columns */
|
||||||
@@ -153,41 +158,6 @@ public class TableMetaDataContext {
|
|||||||
return this.tableColumns;
|
return this.tableColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Does this database support the JDBC 3.0 feature of retrieving generated keys
|
|
||||||
* {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
|
|
||||||
*/
|
|
||||||
public boolean isGetGeneratedKeysSupported() {
|
|
||||||
return this.metaDataProvider.isGetGeneratedKeysSupported();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Does this database support simple query to retrieve generated keys
|
|
||||||
* when the JDBC 3.0 feature is not supported.
|
|
||||||
* {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
|
|
||||||
*/
|
|
||||||
public boolean isGetGeneratedKeysSimulated() {
|
|
||||||
return this.metaDataProvider.isGetGeneratedKeysSimulated();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Does this database support simple query to retrieve generated keys
|
|
||||||
* when the JDBC 3.0 feature is not supported.
|
|
||||||
* {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public String getSimulationQueryForGetGeneratedKey(String tableName, String keyColumnName) {
|
|
||||||
return this.metaDataProvider.getSimpleQueryForGetGeneratedKey(tableName, keyColumnName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is a column name String array for retrieving generated keys supported?
|
|
||||||
* {@link java.sql.Connection#createStruct(String, Object[])}?
|
|
||||||
*/
|
|
||||||
public boolean isGeneratedKeysColumnNameArraySupported() {
|
|
||||||
return this.metaDataProvider.isGeneratedKeysColumnNameArraySupported();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the current meta data with the provided configuration options.
|
* Process the current meta data with the provided configuration options.
|
||||||
@@ -200,6 +170,11 @@ public class TableMetaDataContext {
|
|||||||
this.tableColumns = reconcileColumnsToUse(declaredColumns, generatedKeyNames);
|
this.tableColumns = reconcileColumnsToUse(declaredColumns, generatedKeyNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TableMetaDataProvider obtainMetaDataProvider() {
|
||||||
|
Assert.state(this.metaDataProvider != null, "No TableMetaDataProvider - call processMetaData first");
|
||||||
|
return this.metaDataProvider;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare columns created from metadata with declared columns and return a reconciled list.
|
* Compare columns created from metadata with declared columns and return a reconciled list.
|
||||||
* @param declaredColumns declared column names
|
* @param declaredColumns declared column names
|
||||||
@@ -217,7 +192,7 @@ public class TableMetaDataContext {
|
|||||||
keys.add(key.toUpperCase());
|
keys.add(key.toUpperCase());
|
||||||
}
|
}
|
||||||
List<String> columns = new ArrayList<>();
|
List<String> columns = new ArrayList<>();
|
||||||
for (TableParameterMetaData meta : metaDataProvider.getTableParameterMetaData()) {
|
for (TableParameterMetaData meta : obtainMetaDataProvider().getTableParameterMetaData()) {
|
||||||
if (!keys.contains(meta.getParameterName().toUpperCase())) {
|
if (!keys.contains(meta.getParameterName().toUpperCase())) {
|
||||||
columns.add(meta.getParameterName());
|
columns.add(meta.getParameterName());
|
||||||
}
|
}
|
||||||
@@ -336,7 +311,7 @@ public class TableMetaDataContext {
|
|||||||
*/
|
*/
|
||||||
public int[] createInsertTypes() {
|
public int[] createInsertTypes() {
|
||||||
int[] types = new int[getTableColumns().size()];
|
int[] types = new int[getTableColumns().size()];
|
||||||
List<TableParameterMetaData> parameters = this.metaDataProvider.getTableParameterMetaData();
|
List<TableParameterMetaData> parameters = obtainMetaDataProvider().getTableParameterMetaData();
|
||||||
Map<String, TableParameterMetaData> parameterMap =
|
Map<String, TableParameterMetaData> parameterMap =
|
||||||
new LinkedHashMap<>(parameters.size());
|
new LinkedHashMap<>(parameters.size());
|
||||||
for (TableParameterMetaData tpmd : parameters) {
|
for (TableParameterMetaData tpmd : parameters) {
|
||||||
@@ -361,4 +336,40 @@ public class TableMetaDataContext {
|
|||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this database support the JDBC 3.0 feature of retrieving generated keys
|
||||||
|
* {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
|
||||||
|
*/
|
||||||
|
public boolean isGetGeneratedKeysSupported() {
|
||||||
|
return obtainMetaDataProvider().isGetGeneratedKeysSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this database support simple query to retrieve generated keys
|
||||||
|
* when the JDBC 3.0 feature is not supported.
|
||||||
|
* {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
|
||||||
|
*/
|
||||||
|
public boolean isGetGeneratedKeysSimulated() {
|
||||||
|
return obtainMetaDataProvider().isGetGeneratedKeysSimulated();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does this database support simple query to retrieve generated keys
|
||||||
|
* when the JDBC 3.0 feature is not supported.
|
||||||
|
* {@link java.sql.DatabaseMetaData#supportsGetGeneratedKeys()}?
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public String getSimulationQueryForGetGeneratedKey(String tableName, String keyColumnName) {
|
||||||
|
return obtainMetaDataProvider().getSimpleQueryForGetGeneratedKey(tableName, keyColumnName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is a column name String array for retrieving generated keys supported?
|
||||||
|
* {@link java.sql.Connection#createStruct(String, Object[])}?
|
||||||
|
*/
|
||||||
|
public boolean isGeneratedKeysColumnNameArraySupported() {
|
||||||
|
return obtainMetaDataProvider().isGeneratedKeysColumnNameArraySupported();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import java.sql.SQLException;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for JDBC {@link javax.sql.DataSource} implementations
|
* Abstract base class for JDBC {@link javax.sql.DataSource} implementations
|
||||||
@@ -58,8 +57,7 @@ public abstract class AbstractDriverBasedDataSource extends AbstractDataSource {
|
|||||||
* @see java.sql.Driver#connect(String, java.util.Properties)
|
* @see java.sql.Driver#connect(String, java.util.Properties)
|
||||||
*/
|
*/
|
||||||
public void setUrl(@Nullable String url) {
|
public void setUrl(@Nullable String url) {
|
||||||
Assert.hasText(url, "Property 'url' must not be empty");
|
this.url = (url != null ? url.trim() : null);
|
||||||
this.url = url.trim();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class CustomSQLErrorCodesTranslation {
|
|||||||
|
|
||||||
private String[] errorCodes = new String[0];
|
private String[] errorCodes = new String[0];
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private Class<?> exceptionClass;
|
private Class<?> exceptionClass;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -79,11 +79,11 @@ import org.springframework.util.Assert;
|
|||||||
public class TransactionAwareConnectionFactoryProxy
|
public class TransactionAwareConnectionFactoryProxy
|
||||||
implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory {
|
implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory {
|
||||||
|
|
||||||
private boolean synchedLocalTransactionAllowed = false;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private ConnectionFactory targetConnectionFactory;
|
private ConnectionFactory targetConnectionFactory;
|
||||||
|
|
||||||
|
private boolean synchedLocalTransactionAllowed = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new TransactionAwareConnectionFactoryProxy.
|
* Create a new TransactionAwareConnectionFactoryProxy.
|
||||||
@@ -103,16 +103,18 @@ public class TransactionAwareConnectionFactoryProxy
|
|||||||
/**
|
/**
|
||||||
* Set the target ConnectionFactory that this ConnectionFactory should delegate to.
|
* Set the target ConnectionFactory that this ConnectionFactory should delegate to.
|
||||||
*/
|
*/
|
||||||
public final void setTargetConnectionFactory(@Nullable ConnectionFactory targetConnectionFactory) {
|
public final void setTargetConnectionFactory(ConnectionFactory targetConnectionFactory) {
|
||||||
|
Assert.notNull(targetConnectionFactory, "'targetConnectionFactory' must not be null");
|
||||||
this.targetConnectionFactory = targetConnectionFactory;
|
this.targetConnectionFactory = targetConnectionFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the target ConnectionFactory that this ConnectionFactory should delegate to.
|
* Return the target ConnectionFactory that this ConnectionFactory should delegate to.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
protected ConnectionFactory getTargetConnectionFactory() {
|
protected ConnectionFactory getTargetConnectionFactory() {
|
||||||
return this.targetConnectionFactory;
|
ConnectionFactory target = this.targetConnectionFactory;
|
||||||
|
Assert.state(target != null, "'targetConnectionFactory' is required");
|
||||||
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,19 +143,19 @@ public class TransactionAwareConnectionFactoryProxy
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection createConnection() throws JMSException {
|
public Connection createConnection() throws JMSException {
|
||||||
Connection targetConnection = this.targetConnectionFactory.createConnection();
|
Connection targetConnection = getTargetConnectionFactory().createConnection();
|
||||||
return getTransactionAwareConnectionProxy(targetConnection);
|
return getTransactionAwareConnectionProxy(targetConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection createConnection(String username, String password) throws JMSException {
|
public Connection createConnection(String username, String password) throws JMSException {
|
||||||
Connection targetConnection = obtainTargetConnectionFactory().createConnection(username, password);
|
Connection targetConnection = getTargetConnectionFactory().createConnection(username, password);
|
||||||
return getTransactionAwareConnectionProxy(targetConnection);
|
return getTransactionAwareConnectionProxy(targetConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueueConnection createQueueConnection() throws JMSException {
|
public QueueConnection createQueueConnection() throws JMSException {
|
||||||
ConnectionFactory target = obtainTargetConnectionFactory();
|
ConnectionFactory target = getTargetConnectionFactory();
|
||||||
if (!(target instanceof QueueConnectionFactory)) {
|
if (!(target instanceof QueueConnectionFactory)) {
|
||||||
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no QueueConnectionFactory");
|
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no QueueConnectionFactory");
|
||||||
}
|
}
|
||||||
@@ -163,7 +165,7 @@ public class TransactionAwareConnectionFactoryProxy
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueueConnection createQueueConnection(String username, String password) throws JMSException {
|
public QueueConnection createQueueConnection(String username, String password) throws JMSException {
|
||||||
ConnectionFactory target = obtainTargetConnectionFactory();
|
ConnectionFactory target = getTargetConnectionFactory();
|
||||||
if (!(target instanceof QueueConnectionFactory)) {
|
if (!(target instanceof QueueConnectionFactory)) {
|
||||||
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no QueueConnectionFactory");
|
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no QueueConnectionFactory");
|
||||||
}
|
}
|
||||||
@@ -173,7 +175,7 @@ public class TransactionAwareConnectionFactoryProxy
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TopicConnection createTopicConnection() throws JMSException {
|
public TopicConnection createTopicConnection() throws JMSException {
|
||||||
ConnectionFactory target = obtainTargetConnectionFactory();
|
ConnectionFactory target = getTargetConnectionFactory();
|
||||||
if (!(target instanceof TopicConnectionFactory)) {
|
if (!(target instanceof TopicConnectionFactory)) {
|
||||||
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no TopicConnectionFactory");
|
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no TopicConnectionFactory");
|
||||||
}
|
}
|
||||||
@@ -183,7 +185,7 @@ public class TransactionAwareConnectionFactoryProxy
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TopicConnection createTopicConnection(String username, String password) throws JMSException {
|
public TopicConnection createTopicConnection(String username, String password) throws JMSException {
|
||||||
ConnectionFactory target = obtainTargetConnectionFactory();
|
ConnectionFactory target = getTargetConnectionFactory();
|
||||||
if (!(target instanceof TopicConnectionFactory)) {
|
if (!(target instanceof TopicConnectionFactory)) {
|
||||||
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no TopicConnectionFactory");
|
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no TopicConnectionFactory");
|
||||||
}
|
}
|
||||||
@@ -193,28 +195,22 @@ public class TransactionAwareConnectionFactoryProxy
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JMSContext createContext() {
|
public JMSContext createContext() {
|
||||||
return obtainTargetConnectionFactory().createContext();
|
return getTargetConnectionFactory().createContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JMSContext createContext(String userName, String password) {
|
public JMSContext createContext(String userName, String password) {
|
||||||
return obtainTargetConnectionFactory().createContext(userName, password);
|
return getTargetConnectionFactory().createContext(userName, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JMSContext createContext(String userName, String password, int sessionMode) {
|
public JMSContext createContext(String userName, String password, int sessionMode) {
|
||||||
return obtainTargetConnectionFactory().createContext(userName, password, sessionMode);
|
return getTargetConnectionFactory().createContext(userName, password, sessionMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JMSContext createContext(int sessionMode) {
|
public JMSContext createContext(int sessionMode) {
|
||||||
return obtainTargetConnectionFactory().createContext(sessionMode);
|
return getTargetConnectionFactory().createContext(sessionMode);
|
||||||
}
|
|
||||||
|
|
||||||
private ConnectionFactory obtainTargetConnectionFactory() {
|
|
||||||
ConnectionFactory target = getTargetConnectionFactory();
|
|
||||||
Assert.state(target != null, "'targetConnectionFactory' is required");
|
|
||||||
return target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -265,14 +261,14 @@ public class TransactionAwareConnectionFactoryProxy
|
|||||||
}
|
}
|
||||||
else if (Session.class == method.getReturnType()) {
|
else if (Session.class == method.getReturnType()) {
|
||||||
Session session = ConnectionFactoryUtils.getTransactionalSession(
|
Session session = ConnectionFactoryUtils.getTransactionalSession(
|
||||||
obtainTargetConnectionFactory(), this.target, isSynchedLocalTransactionAllowed());
|
getTargetConnectionFactory(), this.target, isSynchedLocalTransactionAllowed());
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
return getCloseSuppressingSessionProxy(session);
|
return getCloseSuppressingSessionProxy(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (QueueSession.class == method.getReturnType()) {
|
else if (QueueSession.class == method.getReturnType()) {
|
||||||
QueueSession session = ConnectionFactoryUtils.getTransactionalQueueSession(
|
QueueSession session = ConnectionFactoryUtils.getTransactionalQueueSession(
|
||||||
(QueueConnectionFactory) obtainTargetConnectionFactory(), (QueueConnection) this.target,
|
(QueueConnectionFactory) getTargetConnectionFactory(), (QueueConnection) this.target,
|
||||||
isSynchedLocalTransactionAllowed());
|
isSynchedLocalTransactionAllowed());
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
return getCloseSuppressingSessionProxy(session);
|
return getCloseSuppressingSessionProxy(session);
|
||||||
@@ -280,7 +276,7 @@ public class TransactionAwareConnectionFactoryProxy
|
|||||||
}
|
}
|
||||||
else if (TopicSession.class == method.getReturnType()) {
|
else if (TopicSession.class == method.getReturnType()) {
|
||||||
TopicSession session = ConnectionFactoryUtils.getTransactionalTopicSession(
|
TopicSession session = ConnectionFactoryUtils.getTransactionalTopicSession(
|
||||||
(TopicConnectionFactory) obtainTargetConnectionFactory(), (TopicConnection) this.target,
|
(TopicConnectionFactory) getTargetConnectionFactory(), (TopicConnection) this.target,
|
||||||
isSynchedLocalTransactionAllowed());
|
isSynchedLocalTransactionAllowed());
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
return getCloseSuppressingSessionProxy(session);
|
return getCloseSuppressingSessionProxy(session);
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Object defaultDestination;
|
private Object defaultDestination;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private MessageConverter messageConverter;
|
private MessageConverter messageConverter;
|
||||||
|
|
||||||
|
|
||||||
@@ -228,13 +229,14 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
|||||||
* @see #receiveAndConvert
|
* @see #receiveAndConvert
|
||||||
* @see org.springframework.jms.support.converter.SimpleMessageConverter
|
* @see org.springframework.jms.support.converter.SimpleMessageConverter
|
||||||
*/
|
*/
|
||||||
public void setMessageConverter(MessageConverter messageConverter) {
|
public void setMessageConverter(@Nullable MessageConverter messageConverter) {
|
||||||
this.messageConverter = messageConverter;
|
this.messageConverter = messageConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the message converter for this template.
|
* Return the message converter for this template.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public MessageConverter getMessageConverter() {
|
public MessageConverter getMessageConverter() {
|
||||||
return this.messageConverter;
|
return this.messageConverter;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ public abstract class AbstractAdaptableMessageListener
|
|||||||
|
|
||||||
private DestinationResolver destinationResolver = new DynamicDestinationResolver();
|
private DestinationResolver destinationResolver = new DynamicDestinationResolver();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private MessageConverter messageConverter = new SimpleMessageConverter();
|
private MessageConverter messageConverter = new SimpleMessageConverter();
|
||||||
|
|
||||||
private final MessagingMessageConverterAdapter messagingMessageConverter = new MessagingMessageConverterAdapter();
|
private final MessagingMessageConverterAdapter messagingMessageConverter = new MessagingMessageConverterAdapter();
|
||||||
|
|||||||
@@ -232,11 +232,15 @@ public abstract class AbstractMethodMessageHandler<T>
|
|||||||
this.returnValueHandlers.addHandlers(initReturnValueHandlers());
|
this.returnValueHandlers.addHandlers(initReturnValueHandlers());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String beanName : this.applicationContext.getBeanNamesForType(Object.class)) {
|
ApplicationContext context = getApplicationContext();
|
||||||
|
if (context == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String beanName : context.getBeanNamesForType(Object.class)) {
|
||||||
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
|
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
|
||||||
Class<?> beanType = null;
|
Class<?> beanType = null;
|
||||||
try {
|
try {
|
||||||
beanType = this.applicationContext.getType(beanName);
|
beanType = context.getType(beanName);
|
||||||
}
|
}
|
||||||
catch (Throwable ex) {
|
catch (Throwable ex) {
|
||||||
// An unresolvable bean type, probably from a lazy bean - let's ignore it.
|
// An unresolvable bean type, probably from a lazy bean - let's ignore it.
|
||||||
@@ -279,8 +283,15 @@ public abstract class AbstractMethodMessageHandler<T>
|
|||||||
* @param handler the handler to check, either an instance of a Spring bean name
|
* @param handler the handler to check, either an instance of a Spring bean name
|
||||||
*/
|
*/
|
||||||
protected final void detectHandlerMethods(final Object handler) {
|
protected final void detectHandlerMethods(final Object handler) {
|
||||||
Class<?> handlerType = (handler instanceof String ?
|
Class<?> handlerType;
|
||||||
this.applicationContext.getType((String) handler) : handler.getClass());
|
if (handler instanceof String) {
|
||||||
|
ApplicationContext context = getApplicationContext();
|
||||||
|
Assert.state(context != null, "ApplicationContext is required for resolving handler bean names");
|
||||||
|
handlerType = context.getType((String) handler);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
handlerType = handler.getClass();
|
||||||
|
}
|
||||||
|
|
||||||
if (handlerType != null) {
|
if (handlerType != null) {
|
||||||
final Class<?> userType = ClassUtils.getUserClass(handlerType);
|
final Class<?> userType = ClassUtils.getUserClass(handlerType);
|
||||||
@@ -338,9 +349,10 @@ public abstract class AbstractMethodMessageHandler<T>
|
|||||||
protected HandlerMethod createHandlerMethod(Object handler, Method method) {
|
protected HandlerMethod createHandlerMethod(Object handler, Method method) {
|
||||||
HandlerMethod handlerMethod;
|
HandlerMethod handlerMethod;
|
||||||
if (handler instanceof String) {
|
if (handler instanceof String) {
|
||||||
|
ApplicationContext context = getApplicationContext();
|
||||||
|
Assert.state(context != null, "ApplicationContext is required for resolving handler bean names");
|
||||||
String beanName = (String) handler;
|
String beanName = (String) handler;
|
||||||
handlerMethod = new HandlerMethod(beanName,
|
handlerMethod = new HandlerMethod(beanName, context.getAutowireCapableBeanFactory(), method);
|
||||||
this.applicationContext.getAutowireCapableBeanFactory(), method);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
handlerMethod = new HandlerMethod(handler, method);
|
handlerMethod = new HandlerMethod(handler, method);
|
||||||
@@ -645,7 +657,7 @@ public abstract class AbstractMethodMessageHandler<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Object result) {
|
public void onSuccess(@Nullable Object result) {
|
||||||
try {
|
try {
|
||||||
MethodParameter returnType = this.handlerMethod.getAsyncReturnValueType(result);
|
MethodParameter returnType = this.handlerMethod.getAsyncReturnValueType(result);
|
||||||
returnValueHandlers.handleReturnValue(result, returnType, this.message);
|
returnValueHandlers.handleReturnValue(result, returnType, this.message);
|
||||||
|
|||||||
@@ -252,7 +252,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
MethodParameter getAsyncReturnValueType(Object returnValue) {
|
MethodParameter getAsyncReturnValueType(@Nullable Object returnValue) {
|
||||||
return new AsyncResultMethodParameter(returnValue);
|
return new AsyncResultMethodParameter(returnValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +264,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
|||||||
|
|
||||||
private final ResolvableType returnType;
|
private final ResolvableType returnType;
|
||||||
|
|
||||||
public AsyncResultMethodParameter(Object returnValue) {
|
public AsyncResultMethodParameter(@Nullable Object returnValue) {
|
||||||
super(-1);
|
super(-1);
|
||||||
this.returnValue = returnValue;
|
this.returnValue = returnValue;
|
||||||
this.returnType = ResolvableType.forType(super.getGenericParameterType()).getGeneric();
|
this.returnType = ResolvableType.forType(super.getGenericParameterType()).getGeneric();
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public class SimpMessagingTemplate extends AbstractMessageSendingTemplate<String
|
|||||||
|
|
||||||
private volatile long sendTimeout = -1;
|
private volatile long sendTimeout = -1;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private MessageHeaderInitializer headerInitializer;
|
private MessageHeaderInitializer headerInitializer;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.EmbeddedValueResolverAware;
|
import org.springframework.context.EmbeddedValueResolverAware;
|
||||||
import org.springframework.context.SmartLifecycle;
|
import org.springframework.context.SmartLifecycle;
|
||||||
@@ -305,8 +306,9 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
|
|||||||
|
|
||||||
|
|
||||||
protected List<HandlerMethodArgumentResolver> initArgumentResolvers() {
|
protected List<HandlerMethodArgumentResolver> initArgumentResolvers() {
|
||||||
ConfigurableBeanFactory beanFactory = (getApplicationContext() instanceof ConfigurableApplicationContext ?
|
ApplicationContext context = getApplicationContext();
|
||||||
((ConfigurableApplicationContext) getApplicationContext()).getBeanFactory() : null);
|
ConfigurableBeanFactory beanFactory = (context instanceof ConfigurableApplicationContext ?
|
||||||
|
((ConfigurableApplicationContext) context).getBeanFactory() : null);
|
||||||
|
|
||||||
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
|
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package org.springframework.messaging.support;
|
package org.springframework.messaging.support;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.messaging.MessageHeaders;
|
import org.springframework.messaging.MessageHeaders;
|
||||||
import org.springframework.util.IdGenerator;
|
import org.springframework.util.IdGenerator;
|
||||||
@@ -31,6 +29,10 @@ import org.springframework.util.IdGenerator;
|
|||||||
*/
|
*/
|
||||||
public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitializer {
|
public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitializer {
|
||||||
|
|
||||||
|
private static final IdGenerator ID_VALUE_NONE_GENERATOR = () -> MessageHeaders.ID_VALUE_NONE;
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private IdGenerator idGenerator;
|
private IdGenerator idGenerator;
|
||||||
|
|
||||||
private boolean enableTimestamp;
|
private boolean enableTimestamp;
|
||||||
@@ -41,20 +43,12 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
|
|||||||
* instances with.
|
* instances with.
|
||||||
* <p>By default this property is set to {@code null} in which case the default
|
* <p>By default this property is set to {@code null} in which case the default
|
||||||
* IdGenerator of {@link org.springframework.messaging.MessageHeaders} is used.
|
* IdGenerator of {@link org.springframework.messaging.MessageHeaders} is used.
|
||||||
* <p>To have no id's generated at all, see {@link #setDisableIdGeneration()}.
|
* <p>To have no ids generated at all, see {@link #setDisableIdGeneration()}.
|
||||||
*/
|
*/
|
||||||
public void setIdGenerator(@Nullable IdGenerator idGenerator) {
|
public void setIdGenerator(@Nullable IdGenerator idGenerator) {
|
||||||
this.idGenerator = idGenerator;
|
this.idGenerator = idGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A shortcut for calling {@link #setIdGenerator(org.springframework.util.IdGenerator)}
|
|
||||||
* with an id generation strategy to disable id generation completely.
|
|
||||||
*/
|
|
||||||
public void setDisableIdGeneration() {
|
|
||||||
this.idGenerator = ID_VALUE_NONE_GENERATOR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the configured {@code IdGenerator}, if any.
|
* Return the configured {@code IdGenerator}, if any.
|
||||||
*/
|
*/
|
||||||
@@ -63,6 +57,14 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
|
|||||||
return this.idGenerator;
|
return this.idGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shortcut for calling {@link #setIdGenerator} with an id generation strategy
|
||||||
|
* to disable id generation completely.
|
||||||
|
*/
|
||||||
|
public void setDisableIdGeneration() {
|
||||||
|
this.idGenerator = ID_VALUE_NONE_GENERATOR;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to enable the automatic addition of the
|
* Whether to enable the automatic addition of the
|
||||||
* {@link org.springframework.messaging.MessageHeaders#TIMESTAMP} header on
|
* {@link org.springframework.messaging.MessageHeaders#TIMESTAMP} header on
|
||||||
@@ -90,12 +92,4 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
|
|||||||
headerAccessor.setEnableTimestamp(isEnableTimestamp());
|
headerAccessor.setEnableTimestamp(isEnableTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static final IdGenerator ID_VALUE_NONE_GENERATOR = new IdGenerator() {
|
|
||||||
@Override
|
|
||||||
public UUID generateId() {
|
|
||||||
return MessageHeaders.ID_VALUE_NONE;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.util.concurrent.TimeoutException;
|
|||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
import reactor.core.publisher.MonoProcessor;
|
import reactor.core.publisher.MonoProcessor;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.concurrent.FailureCallback;
|
import org.springframework.util.concurrent.FailureCallback;
|
||||||
import org.springframework.util.concurrent.ListenableFuture;
|
import org.springframework.util.concurrent.ListenableFuture;
|
||||||
@@ -67,12 +68,14 @@ abstract class AbstractMonoToListenableFutureAdapter<S, T> implements Listenable
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public T get() throws InterruptedException {
|
public T get() throws InterruptedException {
|
||||||
S result = this.monoProcessor.block();
|
S result = this.monoProcessor.block();
|
||||||
return adapt(result);
|
return adapt(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Nullable
|
||||||
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
Assert.notNull(unit, "TimeUnit must not be null");
|
Assert.notNull(unit, "TimeUnit must not be null");
|
||||||
Duration duration = Duration.ofMillis(TimeUnit.MILLISECONDS.convert(timeout, unit));
|
Duration duration = Duration.ofMillis(TimeUnit.MILLISECONDS.convert(timeout, unit));
|
||||||
@@ -111,6 +114,7 @@ abstract class AbstractMonoToListenableFutureAdapter<S, T> implements Listenable
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected abstract T adapt(S result);
|
@Nullable
|
||||||
|
protected abstract T adapt(@Nullable S result);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package org.springframework.messaging.tcp.reactor;
|
|||||||
|
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Mono-to-ListenableFuture adapter where the source and the target from
|
* A Mono-to-ListenableFuture adapter where the source and the target from
|
||||||
* the Promise and the ListenableFuture respectively are of the same type.
|
* the Promise and the ListenableFuture respectively are of the same type.
|
||||||
@@ -33,7 +35,7 @@ class MonoToListenableFutureAdapter<T> extends AbstractMonoToListenableFutureAda
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected T adapt(T result) {
|
protected T adapt(@Nullable T result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public abstract class AbstractJpaVendorAdapter implements JpaVendorAdapter {
|
|||||||
|
|
||||||
private Database database = Database.DEFAULT;
|
private Database database = Database.DEFAULT;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private String databasePlatform;
|
private String databasePlatform;
|
||||||
|
|
||||||
private boolean generateDdl = false;
|
private boolean generateDdl = false;
|
||||||
@@ -47,14 +48,13 @@ public abstract class AbstractJpaVendorAdapter implements JpaVendorAdapter {
|
|||||||
* Specify the target database to operate on, as a value of the {@code Database} enum:
|
* Specify the target database to operate on, as a value of the {@code Database} enum:
|
||||||
* DB2, DERBY, H2, HSQL, INFORMIX, MYSQL, ORACLE, POSTGRESQL, SQL_SERVER, SYBASE
|
* DB2, DERBY, H2, HSQL, INFORMIX, MYSQL, ORACLE, POSTGRESQL, SQL_SERVER, SYBASE
|
||||||
*/
|
*/
|
||||||
public void setDatabase(@Nullable Database database) {
|
public void setDatabase(Database database) {
|
||||||
this.database = database;
|
this.database = database;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the target database to operate on.
|
* Return the target database to operate on.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
protected Database getDatabase() {
|
protected Database getDatabase() {
|
||||||
return this.database;
|
return this.database;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -65,7 +65,7 @@ public class EclipseLinkJpaVendorAdapter extends AbstractJpaVendorAdapter {
|
|||||||
if (getDatabasePlatform() != null) {
|
if (getDatabasePlatform() != null) {
|
||||||
jpaProperties.put(PersistenceUnitProperties.TARGET_DATABASE, getDatabasePlatform());
|
jpaProperties.put(PersistenceUnitProperties.TARGET_DATABASE, getDatabasePlatform());
|
||||||
}
|
}
|
||||||
else if (getDatabase() != null) {
|
else {
|
||||||
String targetDatabase = determineTargetDatabaseName(getDatabase());
|
String targetDatabase = determineTargetDatabaseName(getDatabase());
|
||||||
if (targetDatabase != null) {
|
if (targetDatabase != null) {
|
||||||
jpaProperties.put(PersistenceUnitProperties.TARGET_DATABASE, targetDatabase);
|
jpaProperties.put(PersistenceUnitProperties.TARGET_DATABASE, targetDatabase);
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -18,7 +18,6 @@ package org.springframework.orm.jpa.vendor;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.EntityManagerFactory;
|
import javax.persistence.EntityManagerFactory;
|
||||||
import javax.persistence.spi.PersistenceProvider;
|
import javax.persistence.spi.PersistenceProvider;
|
||||||
@@ -117,7 +116,7 @@ public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {
|
|||||||
if (getDatabasePlatform() != null) {
|
if (getDatabasePlatform() != null) {
|
||||||
jpaProperties.put(AvailableSettings.DIALECT, getDatabasePlatform());
|
jpaProperties.put(AvailableSettings.DIALECT, getDatabasePlatform());
|
||||||
}
|
}
|
||||||
else if (getDatabase() != null) {
|
else {
|
||||||
Class<?> databaseDialectClass = determineDatabaseDialectClass(getDatabase());
|
Class<?> databaseDialectClass = determineDatabaseDialectClass(getDatabase());
|
||||||
if (databaseDialectClass != null) {
|
if (databaseDialectClass != null) {
|
||||||
jpaProperties.put(AvailableSettings.DIALECT, databaseDialectClass.getName());
|
jpaProperties.put(AvailableSettings.DIALECT, databaseDialectClass.getName());
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
|
|||||||
|
|
||||||
private List<MediaType> supportedMediaTypes = Collections.emptyList();
|
private List<MediaType> supportedMediaTypes = Collections.emptyList();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private Charset defaultCharset;
|
private Charset defaultCharset;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -75,8 +75,10 @@ public class WebDataBinder extends DataBinder {
|
|||||||
*/
|
*/
|
||||||
public static final String DEFAULT_FIELD_DEFAULT_PREFIX = "!";
|
public static final String DEFAULT_FIELD_DEFAULT_PREFIX = "!";
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private String fieldMarkerPrefix = DEFAULT_FIELD_MARKER_PREFIX;
|
private String fieldMarkerPrefix = DEFAULT_FIELD_MARKER_PREFIX;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private String fieldDefaultPrefix = DEFAULT_FIELD_DEFAULT_PREFIX;
|
private String fieldDefaultPrefix = DEFAULT_FIELD_DEFAULT_PREFIX;
|
||||||
|
|
||||||
private boolean bindEmptyMultipartFiles = true;
|
private boolean bindEmptyMultipartFiles = true;
|
||||||
@@ -124,13 +126,14 @@ public class WebDataBinder extends DataBinder {
|
|||||||
* detect an empty field and automatically reset its value.
|
* detect an empty field and automatically reset its value.
|
||||||
* @see #DEFAULT_FIELD_MARKER_PREFIX
|
* @see #DEFAULT_FIELD_MARKER_PREFIX
|
||||||
*/
|
*/
|
||||||
public void setFieldMarkerPrefix(String fieldMarkerPrefix) {
|
public void setFieldMarkerPrefix(@Nullable String fieldMarkerPrefix) {
|
||||||
this.fieldMarkerPrefix = fieldMarkerPrefix;
|
this.fieldMarkerPrefix = fieldMarkerPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the prefix for parameters that mark potentially empty fields.
|
* Return the prefix for parameters that mark potentially empty fields.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public String getFieldMarkerPrefix() {
|
public String getFieldMarkerPrefix() {
|
||||||
return this.fieldMarkerPrefix;
|
return this.fieldMarkerPrefix;
|
||||||
}
|
}
|
||||||
@@ -149,13 +152,14 @@ public class WebDataBinder extends DataBinder {
|
|||||||
* marker for the given field.
|
* marker for the given field.
|
||||||
* @see #DEFAULT_FIELD_DEFAULT_PREFIX
|
* @see #DEFAULT_FIELD_DEFAULT_PREFIX
|
||||||
*/
|
*/
|
||||||
public void setFieldDefaultPrefix(String fieldDefaultPrefix) {
|
public void setFieldDefaultPrefix(@Nullable String fieldDefaultPrefix) {
|
||||||
this.fieldDefaultPrefix = fieldDefaultPrefix;
|
this.fieldDefaultPrefix = fieldDefaultPrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the prefix for parameters that mark default fields.
|
* Return the prefix for parameters that mark default fields.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public String getFieldDefaultPrefix() {
|
public String getFieldDefaultPrefix() {
|
||||||
return this.fieldDefaultPrefix;
|
return this.fieldDefaultPrefix;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
|
|||||||
@Override
|
@Override
|
||||||
public void setServletConfig(@Nullable ServletConfig servletConfig) {
|
public void setServletConfig(@Nullable ServletConfig servletConfig) {
|
||||||
this.servletConfig = servletConfig;
|
this.servletConfig = servletConfig;
|
||||||
if (this.servletContext == null) {
|
if (servletConfig != null && this.servletContext == null) {
|
||||||
setServletContext(servletConfig.getServletContext());
|
setServletContext(servletConfig.getServletContext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,7 +131,9 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
|
|||||||
@Override
|
@Override
|
||||||
public void setNamespace(@Nullable String namespace) {
|
public void setNamespace(@Nullable String namespace) {
|
||||||
this.namespace = namespace;
|
this.namespace = namespace;
|
||||||
setDisplayName(namespace != null ? "WebApplicationContext for namespace '" + namespace + "'" : null);
|
if (namespace != null) {
|
||||||
|
setDisplayName("WebApplicationContext for namespace '" + namespace + "'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class StaticWebApplicationContext extends StaticApplicationContext
|
|||||||
@Override
|
@Override
|
||||||
public void setServletConfig(@Nullable ServletConfig servletConfig) {
|
public void setServletConfig(@Nullable ServletConfig servletConfig) {
|
||||||
this.servletConfig = servletConfig;
|
this.servletConfig = servletConfig;
|
||||||
if (this.servletContext == null) {
|
if (servletConfig != null && this.servletContext == null) {
|
||||||
this.servletContext = servletConfig.getServletContext();
|
this.servletContext = servletConfig.getServletContext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,9 @@ public class StaticWebApplicationContext extends StaticApplicationContext
|
|||||||
@Override
|
@Override
|
||||||
public void setNamespace(@Nullable String namespace) {
|
public void setNamespace(@Nullable String namespace) {
|
||||||
this.namespace = namespace;
|
this.namespace = namespace;
|
||||||
setDisplayName(namespace != null ? "WebApplicationContext for namespace '" + namespace + "'" : null);
|
if (namespace != null) {
|
||||||
|
setDisplayName("WebApplicationContext for namespace '" + namespace + "'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ public class RedirectView extends AbstractUrlBasedView {
|
|||||||
|
|
||||||
private boolean propagateQuery = false;
|
private boolean propagateQuery = false;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private String[] hosts;
|
private String[] hosts;
|
||||||
|
|
||||||
|
|
||||||
@@ -111,17 +112,14 @@ public class RedirectView extends AbstractUrlBasedView {
|
|||||||
* {@link HttpStatus#TEMPORARY_REDIRECT} or
|
* {@link HttpStatus#TEMPORARY_REDIRECT} or
|
||||||
* {@link HttpStatus#PERMANENT_REDIRECT}.
|
* {@link HttpStatus#PERMANENT_REDIRECT}.
|
||||||
*/
|
*/
|
||||||
public void setStatusCode(@Nullable HttpStatus statusCode) {
|
public void setStatusCode(HttpStatus statusCode) {
|
||||||
if (statusCode != null) {
|
Assert.isTrue(statusCode.is3xxRedirection(), "Must be a redirection (3xx status code)");
|
||||||
Assert.isTrue(statusCode.is3xxRedirection(), "Must be a redirection (3xx status code)");
|
|
||||||
}
|
|
||||||
this.statusCode = statusCode;
|
this.statusCode = statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the redirect status code to use.
|
* Get the redirect status code to use.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
public HttpStatus getStatusCode() {
|
public HttpStatus getStatusCode() {
|
||||||
return this.statusCode;
|
return this.statusCode;
|
||||||
}
|
}
|
||||||
@@ -150,13 +148,14 @@ public class RedirectView extends AbstractUrlBasedView {
|
|||||||
* <p>If not set (the default) all redirect URLs are encoded.
|
* <p>If not set (the default) all redirect URLs are encoded.
|
||||||
* @param hosts one or more application hosts
|
* @param hosts one or more application hosts
|
||||||
*/
|
*/
|
||||||
public void setHosts(String... hosts) {
|
public void setHosts(@Nullable String... hosts) {
|
||||||
this.hosts = hosts;
|
this.hosts = hosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the configured application hosts.
|
* Return the configured application hosts.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public String[] getHosts() {
|
public String[] getHosts() {
|
||||||
return this.hosts;
|
return this.hosts;
|
||||||
}
|
}
|
||||||
@@ -165,9 +164,6 @@ public class RedirectView extends AbstractUrlBasedView {
|
|||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
super.afterPropertiesSet();
|
super.afterPropertiesSet();
|
||||||
if (getStatusCode() == null) {
|
|
||||||
throw new IllegalArgumentException("Property 'statusCode' is required");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -185,8 +181,8 @@ public class RedirectView extends AbstractUrlBasedView {
|
|||||||
* Convert model to request parameters and redirect to the given URL.
|
* Convert model to request parameters and redirect to the given URL.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Mono<Void> renderInternal(Map<String, Object> model, MediaType contentType,
|
protected Mono<Void> renderInternal(
|
||||||
ServerWebExchange exchange) {
|
Map<String, Object> model, @Nullable MediaType contentType, ServerWebExchange exchange) {
|
||||||
|
|
||||||
String targetUrl = createTargetUrl(model, exchange);
|
String targetUrl = createTargetUrl(model, exchange);
|
||||||
return sendRedirect(targetUrl, exchange);
|
return sendRedirect(targetUrl, exchange);
|
||||||
@@ -296,10 +292,7 @@ public class RedirectView extends AbstractUrlBasedView {
|
|||||||
ServerHttpResponse response = exchange.getResponse();
|
ServerHttpResponse response = exchange.getResponse();
|
||||||
String encodedURL = (isRemoteHost(targetUrl) ? targetUrl : response.encodeUrl(targetUrl));
|
String encodedURL = (isRemoteHost(targetUrl) ? targetUrl : response.encodeUrl(targetUrl));
|
||||||
response.getHeaders().setLocation(URI.create(encodedURL));
|
response.getHeaders().setLocation(URI.create(encodedURL));
|
||||||
HttpStatus status = getStatusCode();
|
response.setStatusCode(getStatusCode());
|
||||||
if (status != null) {
|
|
||||||
response.setStatusCode(status);
|
|
||||||
}
|
|
||||||
return Mono.empty();
|
return Mono.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,8 +105,6 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte
|
|||||||
* Specify whether this resolver's cookies should be compliant with BCP 47
|
* Specify whether this resolver's cookies should be compliant with BCP 47
|
||||||
* language tags instead of Java's legacy locale specification format.
|
* language tags instead of Java's legacy locale specification format.
|
||||||
* The default is {@code false}.
|
* The default is {@code false}.
|
||||||
* <p>Note: This mode requires JDK 7 or higher. Set this flag to {@code true}
|
|
||||||
* for BCP 47 compliance on JDK 7+ only.
|
|
||||||
* @since 4.3
|
* @since 4.3
|
||||||
* @see Locale#forLanguageTag(String)
|
* @see Locale#forLanguageTag(String)
|
||||||
* @see Locale#toLanguageTag()
|
* @see Locale#toLanguageTag()
|
||||||
@@ -182,43 +180,48 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte
|
|||||||
|
|
||||||
private void parseLocaleCookieIfNecessary(HttpServletRequest request) {
|
private void parseLocaleCookieIfNecessary(HttpServletRequest request) {
|
||||||
if (request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME) == null) {
|
if (request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME) == null) {
|
||||||
// Retrieve and parse cookie value.
|
|
||||||
Cookie cookie = WebUtils.getCookie(request, getCookieName());
|
|
||||||
Locale locale = null;
|
Locale locale = null;
|
||||||
TimeZone timeZone = null;
|
TimeZone timeZone = null;
|
||||||
if (cookie != null) {
|
|
||||||
String value = cookie.getValue();
|
// Retrieve and parse cookie value.
|
||||||
String localePart = value;
|
String cookieName = getCookieName();
|
||||||
String timeZonePart = null;
|
if (cookieName != null) {
|
||||||
int spaceIndex = localePart.indexOf(' ');
|
Cookie cookie = WebUtils.getCookie(request, cookieName);
|
||||||
if (spaceIndex != -1) {
|
if (cookie != null) {
|
||||||
localePart = value.substring(0, spaceIndex);
|
String value = cookie.getValue();
|
||||||
timeZonePart = value.substring(spaceIndex + 1);
|
String localePart = value;
|
||||||
}
|
String timeZonePart = null;
|
||||||
try {
|
int spaceIndex = localePart.indexOf(' ');
|
||||||
locale = (!"-".equals(localePart) ? parseLocaleValue(localePart) : null);
|
if (spaceIndex != -1) {
|
||||||
if (timeZonePart != null) {
|
localePart = value.substring(0, spaceIndex);
|
||||||
timeZone = StringUtils.parseTimeZoneString(timeZonePart);
|
timeZonePart = value.substring(spaceIndex + 1);
|
||||||
}
|
}
|
||||||
}
|
try {
|
||||||
catch (IllegalArgumentException ex) {
|
locale = (!"-".equals(localePart) ? parseLocaleValue(localePart) : null);
|
||||||
if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) != null) {
|
if (timeZonePart != null) {
|
||||||
// Error dispatch: ignore locale/timezone parse exceptions
|
timeZone = StringUtils.parseTimeZoneString(timeZonePart);
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Ignoring invalid locale cookie '" + getCookieName() +
|
|
||||||
"' with value [" + value + "] due to error dispatch: " + ex.getMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
catch (IllegalArgumentException ex) {
|
||||||
throw new IllegalStateException("Invalid locale cookie '" + getCookieName() +
|
if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) != null) {
|
||||||
"' with value [" + value + "]: " + ex.getMessage());
|
// Error dispatch: ignore locale/timezone parse exceptions
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Ignoring invalid locale cookie '" + cookieName +
|
||||||
|
"' with value [" + value + "] due to error dispatch: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalStateException("Invalid locale cookie '" + cookieName +
|
||||||
|
"' with value [" + value + "]: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("Parsed cookie value [" + cookie.getValue() + "] into locale '" + locale +
|
||||||
|
"'" + (timeZone != null ? " and time zone '" + timeZone.getID() + "'" : ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Parsed cookie value [" + cookie.getValue() + "] into locale '" + locale +
|
|
||||||
"'" + (timeZone != null ? " and time zone '" + timeZone.getID() + "'" : ""));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME,
|
request.setAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME,
|
||||||
(locale != null ? locale : determineDefaultLocale(request)));
|
(locale != null ? locale : determineDefaultLocale(request)));
|
||||||
request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME,
|
request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME,
|
||||||
|
|||||||
@@ -88,11 +88,14 @@ public class CookieThemeResolver extends CookieGenerator implements ThemeResolve
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve cookie value from request.
|
// Retrieve cookie value from request.
|
||||||
Cookie cookie = WebUtils.getCookie(request, getCookieName());
|
String cookieName = getCookieName();
|
||||||
if (cookie != null) {
|
if (cookieName != null) {
|
||||||
String value = cookie.getValue();
|
Cookie cookie = WebUtils.getCookie(request, cookieName);
|
||||||
if (StringUtils.hasText(value)) {
|
if (cookie != null) {
|
||||||
themeName = value;
|
String value = cookie.getValue();
|
||||||
|
if (StringUtils.hasText(value)) {
|
||||||
|
themeName = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user