Nullability fine-tuning around bean properties
Issue: SPR-15720 Issue: SPR-15792
This commit is contained in:
parent
06fc092be2
commit
9fc4fb10b0
|
|
@ -126,7 +126,7 @@ public class FieldRetrievingFactoryBean
|
|||
* @see #setTargetObject
|
||||
*/
|
||||
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());
|
||||
|
||||
private final Map<CacheOperationCacheKey, CacheOperationMetadata> metadataCache =
|
||||
new ConcurrentHashMap<>(1024);
|
||||
private final Map<CacheOperationCacheKey, CacheOperationMetadata> metadataCache = new ConcurrentHashMap<>(1024);
|
||||
|
||||
private final CacheOperationExpressionEvaluator evaluator = new CacheOperationExpressionEvaluator();
|
||||
|
||||
|
|
@ -186,6 +185,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
|||
public void afterSingletonsInstantiated() {
|
||||
if (getCacheResolver() == null) {
|
||||
// Lazily initialize cache resolver via default cache manager...
|
||||
Assert.state(this.beanFactory != null, "CacheResolver or BeanFactory must be set on cache aspect");
|
||||
try {
|
||||
setCacheManager(this.beanFactory.getBean(CacheManager.class));
|
||||
}
|
||||
|
|
@ -289,6 +289,10 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
|||
* @see CacheOperation#cacheResolver
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -38,6 +38,7 @@ public abstract class AbstractResourceBasedMessageSource extends AbstractMessage
|
|||
|
||||
private final Set<String> basenameSet = new LinkedHashSet<>(4);
|
||||
|
||||
@Nullable
|
||||
private String defaultEncoding;
|
||||
|
||||
private boolean fallbackToSystemLocale = true;
|
||||
|
|
|
|||
|
|
@ -535,9 +535,6 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
|
|||
}
|
||||
|
||||
private void assertValidators(Validator... validators) {
|
||||
if (validators == null) {
|
||||
return;
|
||||
}
|
||||
for (Validator validator : validators) {
|
||||
if (validator != null && (getTarget() != null && !validator.supports(getTarget().getClass()))) {
|
||||
throw new IllegalStateException("Invalid target for Validator [" + validator + "]: " + getTarget());
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public class CustomizableThreadCreator implements Serializable {
|
|||
|
||||
private boolean daemon = false;
|
||||
|
||||
@Nullable
|
||||
private ThreadGroup threadGroup;
|
||||
|
||||
private final AtomicInteger threadCount = new AtomicInteger(0);
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ public class ListenableFutureCallbackRegistry<T> {
|
|||
* added callbacks with the given result.
|
||||
* @param result the result to trigger the callbacks with
|
||||
*/
|
||||
public void success(T result) {
|
||||
public void success(@Nullable T result) {
|
||||
synchronized (this.mutex) {
|
||||
this.state = State.SUCCESS;
|
||||
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}.
|
||||
*/
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
|
||||
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
|
||||
* by the JDBC driver used for the database in use.
|
||||
|
|
@ -252,13 +265,13 @@ public class CallMetaDataContext {
|
|||
* @return the appropriate SqlParameter
|
||||
*/
|
||||
public SqlParameter createReturnResultSetParameter(String parameterName, RowMapper<?> rowMapper) {
|
||||
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
|
||||
if (this.metaDataProvider.isReturnResultSetSupported()) {
|
||||
CallMetaDataProvider provider = obtainMetaDataProvider();
|
||||
if (provider.isReturnResultSetSupported()) {
|
||||
return new SqlReturnResultSet(parameterName, rowMapper);
|
||||
}
|
||||
else {
|
||||
if (this.metaDataProvider.isRefCursorSupported()) {
|
||||
return new SqlOutParameter(parameterName, this.metaDataProvider.getRefCursorSqlType(), rowMapper);
|
||||
if (provider.isRefCursorSupported()) {
|
||||
return new SqlOutParameter(parameterName, provider.getRefCursorSqlType(), rowMapper);
|
||||
}
|
||||
else {
|
||||
throw new InvalidDataAccessApiUsageException("Return of a ResultSet from a stored procedure is not supported.");
|
||||
|
|
@ -290,14 +303,6 @@ public class CallMetaDataContext {
|
|||
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,
|
||||
* 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.
|
||||
*/
|
||||
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 Map<String, SqlParameter> declaredParams = new LinkedHashMap<>();
|
||||
|
|
@ -321,7 +326,7 @@ public class CallMetaDataContext {
|
|||
List<String> metaDataParamNames = new ArrayList<>();
|
||||
|
||||
// Get the names of the meta data parameters
|
||||
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
|
||||
for (CallParameterMetaData meta : provider.getCallParameterMetaData()) {
|
||||
if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) {
|
||||
metaDataParamNames.add(lowerCase(meta.getParameterName()));
|
||||
}
|
||||
|
|
@ -338,7 +343,7 @@ public class CallMetaDataContext {
|
|||
throw new IllegalArgumentException("Anonymous parameters not supported for calls - " +
|
||||
"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);
|
||||
if (param instanceof SqlOutParameter) {
|
||||
outParamNames.add(paramName);
|
||||
|
|
@ -360,24 +365,23 @@ public class CallMetaDataContext {
|
|||
List<SqlParameter> workParams = new ArrayList<>();
|
||||
workParams.addAll(declaredReturnParams);
|
||||
|
||||
if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
|
||||
if (!provider.isProcedureColumnMetaDataUsed()) {
|
||||
workParams.addAll(declaredParams.values());
|
||||
return workParams;
|
||||
}
|
||||
|
||||
Map<String, String> limitedInParamNamesMap = new HashMap<>(this.limitedInParameterNames.size());
|
||||
for (String limitedParamName : this.limitedInParameterNames) {
|
||||
limitedInParamNamesMap.put(
|
||||
lowerCase(this.metaDataProvider.parameterNameToUse(limitedParamName)), limitedParamName);
|
||||
limitedInParamNamesMap.put(lowerCase(provider.parameterNameToUse(limitedParamName)), limitedParamName);
|
||||
}
|
||||
|
||||
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
|
||||
for (CallParameterMetaData meta : provider.getCallParameterMetaData()) {
|
||||
String paramName = meta.getParameterName();
|
||||
String paramNameToCheck = 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) ||
|
||||
(meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) {
|
||||
SqlParameter param;
|
||||
|
|
@ -409,7 +413,7 @@ public class CallMetaDataContext {
|
|||
else {
|
||||
if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) {
|
||||
if (!isFunction() && !isReturnValueRequired() && paramName != null &&
|
||||
this.metaDataProvider.byPassReturnParameter(paramName)) {
|
||||
provider.byPassReturnParameter(paramName)) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Bypassing metadata return parameter for '" + paramName + "'");
|
||||
}
|
||||
|
|
@ -417,7 +421,7 @@ public class CallMetaDataContext {
|
|||
else {
|
||||
String returnNameToUse =
|
||||
(StringUtils.hasLength(paramNameToUse) ? paramNameToUse : getFunctionReturnName());
|
||||
workParams.add(this.metaDataProvider.createDefaultOutParameter(returnNameToUse, meta));
|
||||
workParams.add(provider.createDefaultOutParameter(returnNameToUse, meta));
|
||||
if (isFunction()) {
|
||||
setFunctionReturnName(returnNameToUse);
|
||||
outParamNames.add(returnNameToUse);
|
||||
|
|
@ -432,14 +436,14 @@ public class CallMetaDataContext {
|
|||
paramNameToUse = "";
|
||||
}
|
||||
if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) {
|
||||
workParams.add(this.metaDataProvider.createDefaultOutParameter(paramNameToUse, meta));
|
||||
workParams.add(provider.createDefaultOutParameter(paramNameToUse, meta));
|
||||
outParamNames.add(paramNameToUse);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Added metadata out parameter for '" + paramNameToUse + "'");
|
||||
}
|
||||
}
|
||||
else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) {
|
||||
workParams.add(this.metaDataProvider.createDefaultInOutParameter(paramNameToUse, meta));
|
||||
workParams.add(provider.createDefaultInOutParameter(paramNameToUse, meta));
|
||||
outParamNames.add(paramNameToUse);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Added metadata in out parameter for '" + paramNameToUse + "'");
|
||||
|
|
@ -448,7 +452,7 @@ public class CallMetaDataContext {
|
|||
else {
|
||||
if (this.limitedInParameterNames.isEmpty() ||
|
||||
limitedInParamNamesMap.containsKey(lowerCase(paramNameToUse))) {
|
||||
workParams.add(this.metaDataProvider.createDefaultInParameter(paramNameToUse, meta));
|
||||
workParams.add(provider.createDefaultInParameter(paramNameToUse, meta));
|
||||
if (logger.isDebugEnabled()) {
|
||||
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
|
||||
*/
|
||||
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
|
||||
// since the database metadata is not necessarily providing case sensitive parameter names.
|
||||
Map<String, String> caseInsensitiveParameterNames =
|
||||
|
|
@ -485,7 +487,7 @@ public class CallMetaDataContext {
|
|||
for (SqlParameter parameter : this.callParameters) {
|
||||
if (parameter.isInputValueProvided()) {
|
||||
String parameterName = parameter.getName();
|
||||
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
|
||||
String parameterNameToMatch = obtainMetaDataProvider().parameterNameToUse(parameterName);
|
||||
if (parameterNameToMatch != null) {
|
||||
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
|
||||
*/
|
||||
public Map<String, ?> matchInParameterValuesWithCallParameters(Map<String, ?> inParameters) {
|
||||
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
|
||||
if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
|
||||
CallMetaDataProvider provider = obtainMetaDataProvider();
|
||||
if (!provider.isProcedureColumnMetaDataUsed()) {
|
||||
return inParameters;
|
||||
}
|
||||
|
||||
|
|
@ -547,7 +549,7 @@ public class CallMetaDataContext {
|
|||
for (SqlParameter parameter : this.callParameters) {
|
||||
if (parameter.isInputValueProvided()) {
|
||||
String parameterName = parameter.getName();
|
||||
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
|
||||
String parameterNameToMatch = provider.parameterNameToUse(parameterName);
|
||||
if (parameterNameToMatch != null) {
|
||||
callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName);
|
||||
}
|
||||
|
|
@ -556,7 +558,7 @@ public class CallMetaDataContext {
|
|||
|
||||
Map<String, Object> matchedParameters = new HashMap<>(inParameters.size());
|
||||
for (String parameterName : inParameters.keySet()) {
|
||||
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
|
||||
String parameterNameToMatch = provider.parameterNameToUse(parameterName);
|
||||
String callParameterName = callParameterNames.get(lowerCase(parameterNameToMatch));
|
||||
if (callParameterName == null) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
|
@ -577,7 +579,7 @@ public class CallMetaDataContext {
|
|||
|
||||
if (matchedParameters.size() < callParameterNames.size()) {
|
||||
for (String parameterName : callParameterNames.keySet()) {
|
||||
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
|
||||
String parameterNameToMatch = provider.parameterNameToUse(parameterName);
|
||||
String callParameterName = callParameterNames.get(lowerCase(parameterNameToMatch));
|
||||
if (!matchedParameters.containsKey(callParameterName)) {
|
||||
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.support.JdbcUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Class to manage context metadata used for the configuration
|
||||
|
|
@ -47,13 +48,16 @@ public class TableMetaDataContext {
|
|||
/** Logger available to subclasses */
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
/** name of table for this context **/
|
||||
/** Name of table for this context */
|
||||
@Nullable
|
||||
private String tableName;
|
||||
|
||||
/** name of catalog for this context **/
|
||||
/** Name of catalog for this context */
|
||||
@Nullable
|
||||
private String catalogName;
|
||||
|
||||
/** name of schema for this context **/
|
||||
/** Name of schema for this context */
|
||||
@Nullable
|
||||
private String schemaName;
|
||||
|
||||
/** List of columns objects to be used in this context */
|
||||
|
|
@ -66,6 +70,7 @@ public class TableMetaDataContext {
|
|||
private boolean overrideIncludeSynonymsDefault = false;
|
||||
|
||||
/** the provider of table meta data */
|
||||
@Nullable
|
||||
private TableMetaDataProvider metaDataProvider;
|
||||
|
||||
/** are we using generated key columns */
|
||||
|
|
@ -153,41 +158,6 @@ public class TableMetaDataContext {
|
|||
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.
|
||||
|
|
@ -200,6 +170,11 @@ public class TableMetaDataContext {
|
|||
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.
|
||||
* @param declaredColumns declared column names
|
||||
|
|
@ -217,7 +192,7 @@ public class TableMetaDataContext {
|
|||
keys.add(key.toUpperCase());
|
||||
}
|
||||
List<String> columns = new ArrayList<>();
|
||||
for (TableParameterMetaData meta : metaDataProvider.getTableParameterMetaData()) {
|
||||
for (TableParameterMetaData meta : obtainMetaDataProvider().getTableParameterMetaData()) {
|
||||
if (!keys.contains(meta.getParameterName().toUpperCase())) {
|
||||
columns.add(meta.getParameterName());
|
||||
}
|
||||
|
|
@ -336,7 +311,7 @@ public class TableMetaDataContext {
|
|||
*/
|
||||
public int[] createInsertTypes() {
|
||||
int[] types = new int[getTableColumns().size()];
|
||||
List<TableParameterMetaData> parameters = this.metaDataProvider.getTableParameterMetaData();
|
||||
List<TableParameterMetaData> parameters = obtainMetaDataProvider().getTableParameterMetaData();
|
||||
Map<String, TableParameterMetaData> parameterMap =
|
||||
new LinkedHashMap<>(parameters.size());
|
||||
for (TableParameterMetaData tpmd : parameters) {
|
||||
|
|
@ -361,4 +336,40 @@ public class TableMetaDataContext {
|
|||
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 org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*/
|
||||
public void setUrl(@Nullable String url) {
|
||||
Assert.hasText(url, "Property 'url' must not be empty");
|
||||
this.url = url.trim();
|
||||
this.url = (url != null ? url.trim() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ public class CustomSQLErrorCodesTranslation {
|
|||
|
||||
private String[] errorCodes = new String[0];
|
||||
|
||||
@Nullable
|
||||
private Class<?> exceptionClass;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -79,11 +79,11 @@ import org.springframework.util.Assert;
|
|||
public class TransactionAwareConnectionFactoryProxy
|
||||
implements ConnectionFactory, QueueConnectionFactory, TopicConnectionFactory {
|
||||
|
||||
private boolean synchedLocalTransactionAllowed = false;
|
||||
|
||||
@Nullable
|
||||
private ConnectionFactory targetConnectionFactory;
|
||||
|
||||
private boolean synchedLocalTransactionAllowed = false;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new TransactionAwareConnectionFactoryProxy.
|
||||
|
|
@ -103,16 +103,18 @@ public class TransactionAwareConnectionFactoryProxy
|
|||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the target ConnectionFactory that this ConnectionFactory should delegate to.
|
||||
*/
|
||||
@Nullable
|
||||
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
|
||||
public Connection createConnection() throws JMSException {
|
||||
Connection targetConnection = this.targetConnectionFactory.createConnection();
|
||||
Connection targetConnection = getTargetConnectionFactory().createConnection();
|
||||
return getTransactionAwareConnectionProxy(targetConnection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection createConnection(String username, String password) throws JMSException {
|
||||
Connection targetConnection = obtainTargetConnectionFactory().createConnection(username, password);
|
||||
Connection targetConnection = getTargetConnectionFactory().createConnection(username, password);
|
||||
return getTransactionAwareConnectionProxy(targetConnection);
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueueConnection createQueueConnection() throws JMSException {
|
||||
ConnectionFactory target = obtainTargetConnectionFactory();
|
||||
ConnectionFactory target = getTargetConnectionFactory();
|
||||
if (!(target instanceof QueueConnectionFactory)) {
|
||||
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no QueueConnectionFactory");
|
||||
}
|
||||
|
|
@ -163,7 +165,7 @@ public class TransactionAwareConnectionFactoryProxy
|
|||
|
||||
@Override
|
||||
public QueueConnection createQueueConnection(String username, String password) throws JMSException {
|
||||
ConnectionFactory target = obtainTargetConnectionFactory();
|
||||
ConnectionFactory target = getTargetConnectionFactory();
|
||||
if (!(target instanceof QueueConnectionFactory)) {
|
||||
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no QueueConnectionFactory");
|
||||
}
|
||||
|
|
@ -173,7 +175,7 @@ public class TransactionAwareConnectionFactoryProxy
|
|||
|
||||
@Override
|
||||
public TopicConnection createTopicConnection() throws JMSException {
|
||||
ConnectionFactory target = obtainTargetConnectionFactory();
|
||||
ConnectionFactory target = getTargetConnectionFactory();
|
||||
if (!(target instanceof TopicConnectionFactory)) {
|
||||
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no TopicConnectionFactory");
|
||||
}
|
||||
|
|
@ -183,7 +185,7 @@ public class TransactionAwareConnectionFactoryProxy
|
|||
|
||||
@Override
|
||||
public TopicConnection createTopicConnection(String username, String password) throws JMSException {
|
||||
ConnectionFactory target = obtainTargetConnectionFactory();
|
||||
ConnectionFactory target = getTargetConnectionFactory();
|
||||
if (!(target instanceof TopicConnectionFactory)) {
|
||||
throw new javax.jms.IllegalStateException("'targetConnectionFactory' is no TopicConnectionFactory");
|
||||
}
|
||||
|
|
@ -193,28 +195,22 @@ public class TransactionAwareConnectionFactoryProxy
|
|||
|
||||
@Override
|
||||
public JMSContext createContext() {
|
||||
return obtainTargetConnectionFactory().createContext();
|
||||
return getTargetConnectionFactory().createContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JMSContext createContext(String userName, String password) {
|
||||
return obtainTargetConnectionFactory().createContext(userName, password);
|
||||
return getTargetConnectionFactory().createContext(userName, password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JMSContext createContext(String userName, String password, int sessionMode) {
|
||||
return obtainTargetConnectionFactory().createContext(userName, password, sessionMode);
|
||||
return getTargetConnectionFactory().createContext(userName, password, sessionMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JMSContext createContext(int sessionMode) {
|
||||
return obtainTargetConnectionFactory().createContext(sessionMode);
|
||||
}
|
||||
|
||||
private ConnectionFactory obtainTargetConnectionFactory() {
|
||||
ConnectionFactory target = getTargetConnectionFactory();
|
||||
Assert.state(target != null, "'targetConnectionFactory' is required");
|
||||
return target;
|
||||
return getTargetConnectionFactory().createContext(sessionMode);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -265,14 +261,14 @@ public class TransactionAwareConnectionFactoryProxy
|
|||
}
|
||||
else if (Session.class == method.getReturnType()) {
|
||||
Session session = ConnectionFactoryUtils.getTransactionalSession(
|
||||
obtainTargetConnectionFactory(), this.target, isSynchedLocalTransactionAllowed());
|
||||
getTargetConnectionFactory(), this.target, isSynchedLocalTransactionAllowed());
|
||||
if (session != null) {
|
||||
return getCloseSuppressingSessionProxy(session);
|
||||
}
|
||||
}
|
||||
else if (QueueSession.class == method.getReturnType()) {
|
||||
QueueSession session = ConnectionFactoryUtils.getTransactionalQueueSession(
|
||||
(QueueConnectionFactory) obtainTargetConnectionFactory(), (QueueConnection) this.target,
|
||||
(QueueConnectionFactory) getTargetConnectionFactory(), (QueueConnection) this.target,
|
||||
isSynchedLocalTransactionAllowed());
|
||||
if (session != null) {
|
||||
return getCloseSuppressingSessionProxy(session);
|
||||
|
|
@ -280,7 +276,7 @@ public class TransactionAwareConnectionFactoryProxy
|
|||
}
|
||||
else if (TopicSession.class == method.getReturnType()) {
|
||||
TopicSession session = ConnectionFactoryUtils.getTransactionalTopicSession(
|
||||
(TopicConnectionFactory) obtainTargetConnectionFactory(), (TopicConnection) this.target,
|
||||
(TopicConnectionFactory) getTargetConnectionFactory(), (TopicConnection) this.target,
|
||||
isSynchedLocalTransactionAllowed());
|
||||
if (session != null) {
|
||||
return getCloseSuppressingSessionProxy(session);
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
|||
@Nullable
|
||||
private Object defaultDestination;
|
||||
|
||||
@Nullable
|
||||
private MessageConverter messageConverter;
|
||||
|
||||
|
||||
|
|
@ -228,13 +229,14 @@ public class JmsTemplate extends JmsDestinationAccessor implements JmsOperations
|
|||
* @see #receiveAndConvert
|
||||
* @see org.springframework.jms.support.converter.SimpleMessageConverter
|
||||
*/
|
||||
public void setMessageConverter(MessageConverter messageConverter) {
|
||||
public void setMessageConverter(@Nullable MessageConverter messageConverter) {
|
||||
this.messageConverter = messageConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the message converter for this template.
|
||||
*/
|
||||
@Nullable
|
||||
public MessageConverter getMessageConverter() {
|
||||
return this.messageConverter;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ public abstract class AbstractAdaptableMessageListener
|
|||
|
||||
private DestinationResolver destinationResolver = new DynamicDestinationResolver();
|
||||
|
||||
@Nullable
|
||||
private MessageConverter messageConverter = new SimpleMessageConverter();
|
||||
|
||||
private final MessagingMessageConverterAdapter messagingMessageConverter = new MessagingMessageConverterAdapter();
|
||||
|
|
|
|||
|
|
@ -232,11 +232,15 @@ public abstract class AbstractMethodMessageHandler<T>
|
|||
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)) {
|
||||
Class<?> beanType = null;
|
||||
try {
|
||||
beanType = this.applicationContext.getType(beanName);
|
||||
beanType = context.getType(beanName);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// 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
|
||||
*/
|
||||
protected final void detectHandlerMethods(final Object handler) {
|
||||
Class<?> handlerType = (handler instanceof String ?
|
||||
this.applicationContext.getType((String) handler) : handler.getClass());
|
||||
Class<?> handlerType;
|
||||
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) {
|
||||
final Class<?> userType = ClassUtils.getUserClass(handlerType);
|
||||
|
|
@ -338,9 +349,10 @@ public abstract class AbstractMethodMessageHandler<T>
|
|||
protected HandlerMethod createHandlerMethod(Object handler, Method method) {
|
||||
HandlerMethod handlerMethod;
|
||||
if (handler instanceof String) {
|
||||
ApplicationContext context = getApplicationContext();
|
||||
Assert.state(context != null, "ApplicationContext is required for resolving handler bean names");
|
||||
String beanName = (String) handler;
|
||||
handlerMethod = new HandlerMethod(beanName,
|
||||
this.applicationContext.getAutowireCapableBeanFactory(), method);
|
||||
handlerMethod = new HandlerMethod(beanName, context.getAutowireCapableBeanFactory(), method);
|
||||
}
|
||||
else {
|
||||
handlerMethod = new HandlerMethod(handler, method);
|
||||
|
|
@ -645,7 +657,7 @@ public abstract class AbstractMethodMessageHandler<T>
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Object result) {
|
||||
public void onSuccess(@Nullable Object result) {
|
||||
try {
|
||||
MethodParameter returnType = this.handlerMethod.getAsyncReturnValueType(result);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -264,7 +264,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
|||
|
||||
private final ResolvableType returnType;
|
||||
|
||||
public AsyncResultMethodParameter(Object returnValue) {
|
||||
public AsyncResultMethodParameter(@Nullable Object returnValue) {
|
||||
super(-1);
|
||||
this.returnValue = returnValue;
|
||||
this.returnType = ResolvableType.forType(super.getGenericParameterType()).getGeneric();
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ public class SimpMessagingTemplate extends AbstractMessageSendingTemplate<String
|
|||
|
||||
private volatile long sendTimeout = -1;
|
||||
|
||||
@Nullable
|
||||
private MessageHeaderInitializer headerInitializer;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.EmbeddedValueResolverAware;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
|
|
@ -305,8 +306,9 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
|
|||
|
||||
|
||||
protected List<HandlerMethodArgumentResolver> initArgumentResolvers() {
|
||||
ConfigurableBeanFactory beanFactory = (getApplicationContext() instanceof ConfigurableApplicationContext ?
|
||||
((ConfigurableApplicationContext) getApplicationContext()).getBeanFactory() : null);
|
||||
ApplicationContext context = getApplicationContext();
|
||||
ConfigurableBeanFactory beanFactory = (context instanceof ConfigurableApplicationContext ?
|
||||
((ConfigurableApplicationContext) context).getBeanFactory() : null);
|
||||
|
||||
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
package org.springframework.messaging.support;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.util.IdGenerator;
|
||||
|
|
@ -31,6 +29,10 @@ import org.springframework.util.IdGenerator;
|
|||
*/
|
||||
public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitializer {
|
||||
|
||||
private static final IdGenerator ID_VALUE_NONE_GENERATOR = () -> MessageHeaders.ID_VALUE_NONE;
|
||||
|
||||
|
||||
@Nullable
|
||||
private IdGenerator idGenerator;
|
||||
|
||||
private boolean enableTimestamp;
|
||||
|
|
@ -41,20 +43,12 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
|
|||
* instances with.
|
||||
* <p>By default this property is set to {@code null} in which case the default
|
||||
* 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) {
|
||||
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.
|
||||
*/
|
||||
|
|
@ -63,6 +57,14 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
|
|||
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
|
||||
* {@link org.springframework.messaging.MessageHeaders#TIMESTAMP} header on
|
||||
|
|
@ -90,12 +92,4 @@ public class IdTimestampMessageHeaderInitializer implements MessageHeaderInitial
|
|||
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.MonoProcessor;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.concurrent.FailureCallback;
|
||||
import org.springframework.util.concurrent.ListenableFuture;
|
||||
|
|
@ -67,12 +68,14 @@ abstract class AbstractMonoToListenableFutureAdapter<S, T> implements Listenable
|
|||
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public T get() throws InterruptedException {
|
||||
S result = this.monoProcessor.block();
|
||||
return adapt(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
|
||||
Assert.notNull(unit, "TimeUnit must not be null");
|
||||
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 org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A Mono-to-ListenableFuture adapter where the source and the target from
|
||||
* the Promise and the ListenableFuture respectively are of the same type.
|
||||
|
|
@ -33,7 +35,7 @@ class MonoToListenableFutureAdapter<T> extends AbstractMonoToListenableFutureAda
|
|||
}
|
||||
|
||||
@Override
|
||||
protected T adapt(T result) {
|
||||
protected T adapt(@Nullable T result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ public abstract class AbstractJpaVendorAdapter implements JpaVendorAdapter {
|
|||
|
||||
private Database database = Database.DEFAULT;
|
||||
|
||||
@Nullable
|
||||
private String databasePlatform;
|
||||
|
||||
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:
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the target database to operate on.
|
||||
*/
|
||||
@Nullable
|
||||
protected Database getDatabase() {
|
||||
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");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -65,7 +65,7 @@ public class EclipseLinkJpaVendorAdapter extends AbstractJpaVendorAdapter {
|
|||
if (getDatabasePlatform() != null) {
|
||||
jpaProperties.put(PersistenceUnitProperties.TARGET_DATABASE, getDatabasePlatform());
|
||||
}
|
||||
else if (getDatabase() != null) {
|
||||
else {
|
||||
String targetDatabase = determineTargetDatabaseName(getDatabase());
|
||||
if (targetDatabase != null) {
|
||||
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");
|
||||
* 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.Map;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.spi.PersistenceProvider;
|
||||
|
|
@ -117,7 +116,7 @@ public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {
|
|||
if (getDatabasePlatform() != null) {
|
||||
jpaProperties.put(AvailableSettings.DIALECT, getDatabasePlatform());
|
||||
}
|
||||
else if (getDatabase() != null) {
|
||||
else {
|
||||
Class<?> databaseDialectClass = determineDatabaseDialectClass(getDatabase());
|
||||
if (databaseDialectClass != null) {
|
||||
jpaProperties.put(AvailableSettings.DIALECT, databaseDialectClass.getName());
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ public abstract class AbstractHttpMessageConverter<T> implements HttpMessageConv
|
|||
|
||||
private List<MediaType> supportedMediaTypes = Collections.emptyList();
|
||||
|
||||
@Nullable
|
||||
private Charset defaultCharset;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -75,8 +75,10 @@ public class WebDataBinder extends DataBinder {
|
|||
*/
|
||||
public static final String DEFAULT_FIELD_DEFAULT_PREFIX = "!";
|
||||
|
||||
@Nullable
|
||||
private String fieldMarkerPrefix = DEFAULT_FIELD_MARKER_PREFIX;
|
||||
|
||||
@Nullable
|
||||
private String fieldDefaultPrefix = DEFAULT_FIELD_DEFAULT_PREFIX;
|
||||
|
||||
private boolean bindEmptyMultipartFiles = true;
|
||||
|
|
@ -124,13 +126,14 @@ public class WebDataBinder extends DataBinder {
|
|||
* detect an empty field and automatically reset its value.
|
||||
* @see #DEFAULT_FIELD_MARKER_PREFIX
|
||||
*/
|
||||
public void setFieldMarkerPrefix(String fieldMarkerPrefix) {
|
||||
public void setFieldMarkerPrefix(@Nullable String fieldMarkerPrefix) {
|
||||
this.fieldMarkerPrefix = fieldMarkerPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the prefix for parameters that mark potentially empty fields.
|
||||
*/
|
||||
@Nullable
|
||||
public String getFieldMarkerPrefix() {
|
||||
return this.fieldMarkerPrefix;
|
||||
}
|
||||
|
|
@ -149,13 +152,14 @@ public class WebDataBinder extends DataBinder {
|
|||
* marker for the given field.
|
||||
* @see #DEFAULT_FIELD_DEFAULT_PREFIX
|
||||
*/
|
||||
public void setFieldDefaultPrefix(String fieldDefaultPrefix) {
|
||||
public void setFieldDefaultPrefix(@Nullable String fieldDefaultPrefix) {
|
||||
this.fieldDefaultPrefix = fieldDefaultPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the prefix for parameters that mark default fields.
|
||||
*/
|
||||
@Nullable
|
||||
public String getFieldDefaultPrefix() {
|
||||
return this.fieldDefaultPrefix;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
|
|||
@Override
|
||||
public void setServletConfig(@Nullable ServletConfig servletConfig) {
|
||||
this.servletConfig = servletConfig;
|
||||
if (this.servletContext == null) {
|
||||
if (servletConfig != null && this.servletContext == null) {
|
||||
setServletContext(servletConfig.getServletContext());
|
||||
}
|
||||
}
|
||||
|
|
@ -131,7 +131,9 @@ public abstract class AbstractRefreshableWebApplicationContext extends AbstractR
|
|||
@Override
|
||||
public void setNamespace(@Nullable String namespace) {
|
||||
this.namespace = namespace;
|
||||
setDisplayName(namespace != null ? "WebApplicationContext for namespace '" + namespace + "'" : null);
|
||||
if (namespace != null) {
|
||||
setDisplayName("WebApplicationContext for namespace '" + namespace + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public class StaticWebApplicationContext extends StaticApplicationContext
|
|||
@Override
|
||||
public void setServletConfig(@Nullable ServletConfig servletConfig) {
|
||||
this.servletConfig = servletConfig;
|
||||
if (this.servletContext == null) {
|
||||
if (servletConfig != null && this.servletContext == null) {
|
||||
this.servletContext = servletConfig.getServletContext();
|
||||
}
|
||||
}
|
||||
|
|
@ -107,7 +107,9 @@ public class StaticWebApplicationContext extends StaticApplicationContext
|
|||
@Override
|
||||
public void setNamespace(@Nullable String namespace) {
|
||||
this.namespace = namespace;
|
||||
setDisplayName(namespace != null ? "WebApplicationContext for namespace '" + namespace + "'" : null);
|
||||
if (namespace != null) {
|
||||
setDisplayName("WebApplicationContext for namespace '" + namespace + "'");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ public class RedirectView extends AbstractUrlBasedView {
|
|||
|
||||
private boolean propagateQuery = false;
|
||||
|
||||
@Nullable
|
||||
private String[] hosts;
|
||||
|
||||
|
||||
|
|
@ -111,17 +112,14 @@ public class RedirectView extends AbstractUrlBasedView {
|
|||
* {@link HttpStatus#TEMPORARY_REDIRECT} or
|
||||
* {@link HttpStatus#PERMANENT_REDIRECT}.
|
||||
*/
|
||||
public void setStatusCode(@Nullable HttpStatus statusCode) {
|
||||
if (statusCode != null) {
|
||||
Assert.isTrue(statusCode.is3xxRedirection(), "Must be a redirection (3xx status code)");
|
||||
}
|
||||
public void setStatusCode(HttpStatus statusCode) {
|
||||
Assert.isTrue(statusCode.is3xxRedirection(), "Must be a redirection (3xx status code)");
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the redirect status code to use.
|
||||
*/
|
||||
@Nullable
|
||||
public HttpStatus getStatusCode() {
|
||||
return this.statusCode;
|
||||
}
|
||||
|
|
@ -150,13 +148,14 @@ public class RedirectView extends AbstractUrlBasedView {
|
|||
* <p>If not set (the default) all redirect URLs are encoded.
|
||||
* @param hosts one or more application hosts
|
||||
*/
|
||||
public void setHosts(String... hosts) {
|
||||
public void setHosts(@Nullable String... hosts) {
|
||||
this.hosts = hosts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured application hosts.
|
||||
*/
|
||||
@Nullable
|
||||
public String[] getHosts() {
|
||||
return this.hosts;
|
||||
}
|
||||
|
|
@ -165,9 +164,6 @@ public class RedirectView extends AbstractUrlBasedView {
|
|||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
protected Mono<Void> renderInternal(Map<String, Object> model, MediaType contentType,
|
||||
ServerWebExchange exchange) {
|
||||
protected Mono<Void> renderInternal(
|
||||
Map<String, Object> model, @Nullable MediaType contentType, ServerWebExchange exchange) {
|
||||
|
||||
String targetUrl = createTargetUrl(model, exchange);
|
||||
return sendRedirect(targetUrl, exchange);
|
||||
|
|
@ -296,10 +292,7 @@ public class RedirectView extends AbstractUrlBasedView {
|
|||
ServerHttpResponse response = exchange.getResponse();
|
||||
String encodedURL = (isRemoteHost(targetUrl) ? targetUrl : response.encodeUrl(targetUrl));
|
||||
response.getHeaders().setLocation(URI.create(encodedURL));
|
||||
HttpStatus status = getStatusCode();
|
||||
if (status != null) {
|
||||
response.setStatusCode(status);
|
||||
}
|
||||
response.setStatusCode(getStatusCode());
|
||||
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
|
||||
* language tags instead of Java's legacy locale specification format.
|
||||
* 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
|
||||
* @see Locale#forLanguageTag(String)
|
||||
* @see Locale#toLanguageTag()
|
||||
|
|
@ -182,43 +180,48 @@ public class CookieLocaleResolver extends CookieGenerator implements LocaleConte
|
|||
|
||||
private void parseLocaleCookieIfNecessary(HttpServletRequest request) {
|
||||
if (request.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME) == null) {
|
||||
// Retrieve and parse cookie value.
|
||||
Cookie cookie = WebUtils.getCookie(request, getCookieName());
|
||||
Locale locale = null;
|
||||
TimeZone timeZone = null;
|
||||
if (cookie != null) {
|
||||
String value = cookie.getValue();
|
||||
String localePart = value;
|
||||
String timeZonePart = null;
|
||||
int spaceIndex = localePart.indexOf(' ');
|
||||
if (spaceIndex != -1) {
|
||||
localePart = value.substring(0, spaceIndex);
|
||||
timeZonePart = value.substring(spaceIndex + 1);
|
||||
}
|
||||
try {
|
||||
locale = (!"-".equals(localePart) ? parseLocaleValue(localePart) : null);
|
||||
if (timeZonePart != null) {
|
||||
timeZone = StringUtils.parseTimeZoneString(timeZonePart);
|
||||
|
||||
// Retrieve and parse cookie value.
|
||||
String cookieName = getCookieName();
|
||||
if (cookieName != null) {
|
||||
Cookie cookie = WebUtils.getCookie(request, cookieName);
|
||||
if (cookie != null) {
|
||||
String value = cookie.getValue();
|
||||
String localePart = value;
|
||||
String timeZonePart = null;
|
||||
int spaceIndex = localePart.indexOf(' ');
|
||||
if (spaceIndex != -1) {
|
||||
localePart = value.substring(0, spaceIndex);
|
||||
timeZonePart = value.substring(spaceIndex + 1);
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) != null) {
|
||||
// Error dispatch: ignore locale/timezone parse exceptions
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Ignoring invalid locale cookie '" + getCookieName() +
|
||||
"' with value [" + value + "] due to error dispatch: " + ex.getMessage());
|
||||
try {
|
||||
locale = (!"-".equals(localePart) ? parseLocaleValue(localePart) : null);
|
||||
if (timeZonePart != null) {
|
||||
timeZone = StringUtils.parseTimeZoneString(timeZonePart);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Invalid locale cookie '" + getCookieName() +
|
||||
"' with value [" + value + "]: " + ex.getMessage());
|
||||
catch (IllegalArgumentException ex) {
|
||||
if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) != null) {
|
||||
// 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,
|
||||
(locale != null ? locale : determineDefaultLocale(request)));
|
||||
request.setAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME,
|
||||
|
|
|
|||
|
|
@ -88,11 +88,14 @@ public class CookieThemeResolver extends CookieGenerator implements ThemeResolve
|
|||
}
|
||||
|
||||
// Retrieve cookie value from request.
|
||||
Cookie cookie = WebUtils.getCookie(request, getCookieName());
|
||||
if (cookie != null) {
|
||||
String value = cookie.getValue();
|
||||
if (StringUtils.hasText(value)) {
|
||||
themeName = value;
|
||||
String cookieName = getCookieName();
|
||||
if (cookieName != null) {
|
||||
Cookie cookie = WebUtils.getCookie(request, cookieName);
|
||||
if (cookie != null) {
|
||||
String value = cookie.getValue();
|
||||
if (StringUtils.hasText(value)) {
|
||||
themeName = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue