Consistent use of @Nullable across the codebase (even for internals)
Beyond just formally declaring the current behavior, this revision actually enforces non-null behavior in selected signatures now, not tolerating null values anymore when not explicitly documented. It also changes some utility methods with historic null-in/null-out tolerance towards enforced non-null return values, making them a proper citizen in non-null assignments. Some issues are left as to-do: in particular a thorough revision of spring-test, and a few tests with unclear failures (ignored as "TODO: NULLABLE") to be sorted out in a follow-up commit. Issue: SPR-15540
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.dao;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Exception thrown on concurrency failure.
|
||||
*
|
||||
@@ -45,7 +47,7 @@ public class ConcurrencyFailureException extends TransientDataAccessException {
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause from the data access API in use
|
||||
*/
|
||||
public ConcurrencyFailureException(String msg, Throwable cause) {
|
||||
public ConcurrencyFailureException(String msg, @Nullable Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.springframework.dao;
|
||||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Root of the hierarchy of data access exceptions discussed in
|
||||
@@ -52,7 +53,7 @@ public abstract class DataAccessException extends NestedRuntimeException {
|
||||
* @param cause the root cause (usually from using a underlying
|
||||
* data access API such as JDBC)
|
||||
*/
|
||||
public DataAccessException(String msg, Throwable cause) {
|
||||
public DataAccessException(@Nullable String msg, @Nullable Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.dao;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Data access exception thrown when a resource fails completely:
|
||||
* for example, if we can't connect to a database using JDBC.
|
||||
@@ -39,7 +41,7 @@ public class DataAccessResourceFailureException extends NonTransientDataAccessRe
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause from the data access API in use
|
||||
*/
|
||||
public DataAccessResourceFailureException(String msg, Throwable cause) {
|
||||
public DataAccessResourceFailureException(String msg, @Nullable Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.dao;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Exception thrown if certain expected data could not be retrieved, e.g.
|
||||
* when looking up specific data via a known identifier. This exception
|
||||
@@ -40,7 +42,7 @@ public class DataRetrievalFailureException extends NonTransientDataAccessExcepti
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause from the data access API in use
|
||||
*/
|
||||
public DataRetrievalFailureException(String msg, Throwable cause) {
|
||||
public DataRetrievalFailureException(String msg, @Nullable Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.dao;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Root of the hierarchy of data access exceptions that are considered non-transient -
|
||||
* where a retry of the same operation would fail unless the cause of the Exception
|
||||
@@ -42,7 +44,7 @@ public abstract class NonTransientDataAccessException extends DataAccessExceptio
|
||||
* @param cause the root cause (usually from using a underlying
|
||||
* data access API such as JDBC)
|
||||
*/
|
||||
public NonTransientDataAccessException(String msg, Throwable cause) {
|
||||
public NonTransientDataAccessException(@Nullable String msg, @Nullable Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.dao;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Data access exception thrown when a resource fails completely and the failure is permanent.
|
||||
*
|
||||
@@ -39,7 +41,7 @@ public class NonTransientDataAccessResourceException extends NonTransientDataAcc
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause from the data access API in use
|
||||
*/
|
||||
public NonTransientDataAccessResourceException(String msg, Throwable cause) {
|
||||
public NonTransientDataAccessResourceException(String msg, @Nullable Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.dao;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Exception thrown on an optimistic locking violation.
|
||||
*
|
||||
@@ -42,7 +44,7 @@ public class OptimisticLockingFailureException extends ConcurrencyFailureExcepti
|
||||
* @param msg the detail message
|
||||
* @param cause the root cause from the data access API in use
|
||||
*/
|
||||
public OptimisticLockingFailureException(String msg, Throwable cause) {
|
||||
public OptimisticLockingFailureException(String msg, @Nullable Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.dao;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Root of the hierarchy of data access exceptions that are considered transient -
|
||||
* where a previously failed operation might be able to succeed when the operation
|
||||
@@ -42,7 +44,7 @@ public abstract class TransientDataAccessException extends DataAccessException {
|
||||
* @param cause the root cause (usually from using a underlying
|
||||
* data access API such as JDBC)
|
||||
*/
|
||||
public TransientDataAccessException(String msg, Throwable cause) {
|
||||
public TransientDataAccessException(String msg, @Nullable Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.dao;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Normal superclass when we can't distinguish anything more specific
|
||||
* than "something went wrong with the underlying resource": for example,
|
||||
@@ -31,7 +33,7 @@ public abstract class UncategorizedDataAccessException extends NonTransientDataA
|
||||
* @param msg the detail message
|
||||
* @param cause the exception thrown by underlying data access API
|
||||
*/
|
||||
public UncategorizedDataAccessException(String msg, Throwable cause) {
|
||||
public UncategorizedDataAccessException(@Nullable String msg, @Nullable Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -46,7 +46,7 @@ public abstract class DataAccessUtils {
|
||||
* element has been found in the given Collection
|
||||
*/
|
||||
@Nullable
|
||||
public static <T> T singleResult(Collection<T> results) throws IncorrectResultSizeDataAccessException {
|
||||
public static <T> T singleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException {
|
||||
int size = (results != null ? results.size() : 0);
|
||||
if (size == 0) {
|
||||
return null;
|
||||
@@ -137,7 +137,7 @@ public abstract class DataAccessUtils {
|
||||
* not match the specified required type
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T objectResult(@Nullable Collection<?> results, Class<T> requiredType)
|
||||
public static <T> T objectResult(@Nullable Collection<?> results, @Nullable Class<T> requiredType)
|
||||
throws IncorrectResultSizeDataAccessException, TypeMismatchDataAccessException {
|
||||
|
||||
Object result = requiredUniqueResult(results);
|
||||
|
||||
@@ -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.
|
||||
@@ -32,6 +32,7 @@ import org.springframework.transaction.support.AbstractPlatformTransactionManage
|
||||
import org.springframework.transaction.support.DefaultTransactionStatus;
|
||||
import org.springframework.transaction.support.ResourceTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.transaction.PlatformTransactionManager} implementation
|
||||
@@ -106,10 +107,17 @@ public class CciLocalTransactionManager extends AbstractPlatformTransactionManag
|
||||
* Return the CCI ConnectionFactory that this instance manages local
|
||||
* transactions for.
|
||||
*/
|
||||
@Nullable
|
||||
public ConnectionFactory getConnectionFactory() {
|
||||
return this.connectionFactory;
|
||||
}
|
||||
|
||||
private ConnectionFactory obtainConnectionFactory() {
|
||||
ConnectionFactory connectionFactory = getConnectionFactory();
|
||||
Assert.state(connectionFactory != null, "No ConnectionFactory set");
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
if (getConnectionFactory() == null) {
|
||||
@@ -120,14 +128,14 @@ public class CciLocalTransactionManager extends AbstractPlatformTransactionManag
|
||||
|
||||
@Override
|
||||
public Object getResourceFactory() {
|
||||
return getConnectionFactory();
|
||||
return obtainConnectionFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doGetTransaction() {
|
||||
CciLocalTransactionObject txObject = new CciLocalTransactionObject();
|
||||
ConnectionHolder conHolder =
|
||||
(ConnectionHolder) TransactionSynchronizationManager.getResource(getConnectionFactory());
|
||||
(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainConnectionFactory());
|
||||
txObject.setConnectionHolder(conHolder);
|
||||
return txObject;
|
||||
}
|
||||
@@ -136,40 +144,43 @@ public class CciLocalTransactionManager extends AbstractPlatformTransactionManag
|
||||
protected boolean isExistingTransaction(Object transaction) {
|
||||
CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction;
|
||||
// Consider a pre-bound connection as transaction.
|
||||
return (txObject.getConnectionHolder() != null);
|
||||
return txObject.hasConnectionHolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doBegin(Object transaction, TransactionDefinition definition) {
|
||||
CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction;
|
||||
ConnectionFactory connectionFactory = obtainConnectionFactory();
|
||||
Connection con = null;
|
||||
|
||||
try {
|
||||
con = getConnectionFactory().getConnection();
|
||||
con = connectionFactory.getConnection();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Acquired Connection [" + con + "] for local CCI transaction");
|
||||
}
|
||||
|
||||
txObject.setConnectionHolder(new ConnectionHolder(con));
|
||||
txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
|
||||
ConnectionHolder connectionHolder = new ConnectionHolder(con);
|
||||
connectionHolder.setSynchronizedWithTransaction(true);
|
||||
|
||||
con.getLocalTransaction().begin();
|
||||
int timeout = determineTimeout(definition);
|
||||
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
|
||||
txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
|
||||
connectionHolder.setTimeoutInSeconds(timeout);
|
||||
}
|
||||
TransactionSynchronizationManager.bindResource(getConnectionFactory(), txObject.getConnectionHolder());
|
||||
|
||||
txObject.setConnectionHolder(connectionHolder);
|
||||
TransactionSynchronizationManager.bindResource(connectionFactory, connectionHolder);
|
||||
}
|
||||
catch (NotSupportedException ex) {
|
||||
ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory());
|
||||
ConnectionFactoryUtils.releaseConnection(con, connectionFactory);
|
||||
throw new CannotCreateTransactionException("CCI Connection does not support local transactions", ex);
|
||||
}
|
||||
catch (LocalTransactionException ex) {
|
||||
ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory());
|
||||
ConnectionFactoryUtils.releaseConnection(con, connectionFactory);
|
||||
throw new CannotCreateTransactionException("Could not begin local CCI transaction", ex);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory());
|
||||
ConnectionFactoryUtils.releaseConnection(con, connectionFactory);
|
||||
throw new TransactionSystemException("Unexpected failure on begin of CCI local transaction", ex);
|
||||
}
|
||||
}
|
||||
@@ -178,13 +189,13 @@ public class CciLocalTransactionManager extends AbstractPlatformTransactionManag
|
||||
protected Object doSuspend(Object transaction) {
|
||||
CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction;
|
||||
txObject.setConnectionHolder(null);
|
||||
return TransactionSynchronizationManager.unbindResource(getConnectionFactory());
|
||||
return TransactionSynchronizationManager.unbindResource(obtainConnectionFactory());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doResume(Object transaction, Object suspendedResources) {
|
||||
protected void doResume(@Nullable Object transaction, Object suspendedResources) {
|
||||
ConnectionHolder conHolder = (ConnectionHolder) suspendedResources;
|
||||
TransactionSynchronizationManager.bindResource(getConnectionFactory(), conHolder);
|
||||
TransactionSynchronizationManager.bindResource(obtainConnectionFactory(), conHolder);
|
||||
}
|
||||
|
||||
protected boolean isRollbackOnly(Object transaction) throws TransactionException {
|
||||
@@ -241,16 +252,17 @@ public class CciLocalTransactionManager extends AbstractPlatformTransactionManag
|
||||
@Override
|
||||
protected void doCleanupAfterCompletion(Object transaction) {
|
||||
CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction;
|
||||
ConnectionFactory connectionFactory = obtainConnectionFactory();
|
||||
|
||||
// Remove the connection holder from the thread.
|
||||
TransactionSynchronizationManager.unbindResource(getConnectionFactory());
|
||||
TransactionSynchronizationManager.unbindResource(connectionFactory);
|
||||
txObject.getConnectionHolder().clear();
|
||||
|
||||
Connection con = txObject.getConnectionHolder().getConnection();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Releasing CCI Connection [" + con + "] after transaction");
|
||||
}
|
||||
ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory());
|
||||
ConnectionFactoryUtils.releaseConnection(con, connectionFactory);
|
||||
}
|
||||
|
||||
|
||||
@@ -268,8 +280,13 @@ public class CciLocalTransactionManager extends AbstractPlatformTransactionManag
|
||||
}
|
||||
|
||||
public ConnectionHolder getConnectionHolder() {
|
||||
Assert.state(this.connectionHolder != null, "No ConnectionHolder available");
|
||||
return this.connectionHolder;
|
||||
}
|
||||
|
||||
public boolean hasConnectionHolder() {
|
||||
return (this.connectionHolder != null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -163,7 +163,7 @@ public abstract class ConnectionFactoryUtils {
|
||||
* (can be {@code null})
|
||||
* @see #getConnection
|
||||
*/
|
||||
public static void releaseConnection(Connection con, @Nullable ConnectionFactory cf) {
|
||||
public static void releaseConnection(@Nullable Connection con, @Nullable ConnectionFactory cf) {
|
||||
try {
|
||||
doReleaseConnection(con, cf);
|
||||
}
|
||||
@@ -187,7 +187,9 @@ public abstract class ConnectionFactoryUtils {
|
||||
* @throws ResourceException if thrown by JCA CCI methods
|
||||
* @see #doGetConnection
|
||||
*/
|
||||
public static void doReleaseConnection(Connection con, @Nullable ConnectionFactory cf) throws ResourceException {
|
||||
public static void doReleaseConnection(@Nullable Connection con, @Nullable ConnectionFactory cf)
|
||||
throws ResourceException {
|
||||
|
||||
if (con == null || isConnectionTransactional(con, cf)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -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,9 +18,12 @@ package org.springframework.jca.cci.connection;
|
||||
|
||||
import javax.resource.ResourceException;
|
||||
import javax.resource.cci.Connection;
|
||||
import javax.resource.cci.ConnectionFactory;
|
||||
import javax.resource.cci.ConnectionSpec;
|
||||
|
||||
import org.springframework.core.NamedThreadLocal;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* An adapter for a target CCI {@link javax.resource.cci.ConnectionFactory},
|
||||
@@ -128,16 +131,10 @@ public class ConnectionSpecConnectionFactoryAdapter extends DelegatingConnection
|
||||
* @see javax.resource.cci.ConnectionFactory#getConnection(javax.resource.cci.ConnectionSpec)
|
||||
* @see javax.resource.cci.ConnectionFactory#getConnection()
|
||||
*/
|
||||
protected Connection doGetConnection(ConnectionSpec spec) throws ResourceException {
|
||||
if (getTargetConnectionFactory() == null) {
|
||||
throw new IllegalStateException("targetConnectionFactory is required");
|
||||
}
|
||||
if (spec != null) {
|
||||
return getTargetConnectionFactory().getConnection(spec);
|
||||
}
|
||||
else {
|
||||
return getTargetConnectionFactory().getConnection();
|
||||
}
|
||||
protected Connection doGetConnection(@Nullable ConnectionSpec spec) throws ResourceException {
|
||||
ConnectionFactory connectionFactory = getTargetConnectionFactory();
|
||||
Assert.state(connectionFactory != null, "No 'targetConnectionFactory' set");
|
||||
return (spec != null ? connectionFactory.getConnection(spec) : connectionFactory.getConnection());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,8 @@ import javax.resource.cci.RecordFactory;
|
||||
import javax.resource.cci.ResourceAdapterMetaData;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* CCI {@link ConnectionFactory} implementation that delegates all calls
|
||||
@@ -55,10 +57,21 @@ public class DelegatingConnectionFactory implements ConnectionFactory, Initializ
|
||||
/**
|
||||
* Return the target ConnectionFactory that this ConnectionFactory should delegate to.
|
||||
*/
|
||||
@Nullable
|
||||
public ConnectionFactory getTargetConnectionFactory() {
|
||||
return this.targetConnectionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the target {@code ConnectionFactory} for actual use (never {@code null}).
|
||||
* @since 5.0
|
||||
*/
|
||||
protected ConnectionFactory obtainTargetConnectionFactory() {
|
||||
ConnectionFactory connectionFactory = getTargetConnectionFactory();
|
||||
Assert.state(connectionFactory != null, "No 'targetConnectionFactory' set");
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
@@ -70,32 +83,32 @@ public class DelegatingConnectionFactory implements ConnectionFactory, Initializ
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws ResourceException {
|
||||
return getTargetConnectionFactory().getConnection();
|
||||
return obtainTargetConnectionFactory().getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection(ConnectionSpec connectionSpec) throws ResourceException {
|
||||
return getTargetConnectionFactory().getConnection(connectionSpec);
|
||||
return obtainTargetConnectionFactory().getConnection(connectionSpec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecordFactory getRecordFactory() throws ResourceException {
|
||||
return getTargetConnectionFactory().getRecordFactory();
|
||||
return obtainTargetConnectionFactory().getRecordFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceAdapterMetaData getMetaData() throws ResourceException {
|
||||
return getTargetConnectionFactory().getMetaData();
|
||||
return obtainTargetConnectionFactory().getMetaData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reference getReference() throws NamingException {
|
||||
return getTargetConnectionFactory().getReference();
|
||||
return obtainTargetConnectionFactory().getReference();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReference(Reference reference) {
|
||||
getTargetConnectionFactory().setReference(reference);
|
||||
obtainTargetConnectionFactory().setReference(reference);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -30,6 +30,7 @@ import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -177,7 +178,9 @@ public class SingleConnectionFactory extends DelegatingConnectionFactory impleme
|
||||
* @throws javax.resource.ResourceException if thrown by CCI API methods
|
||||
*/
|
||||
protected Connection doCreateConnection() throws ResourceException {
|
||||
return getTargetConnectionFactory().getConnection();
|
||||
ConnectionFactory connectionFactory = getTargetConnectionFactory();
|
||||
Assert.state(connectionFactory != null, "No 'targetConnectionFactory' set");
|
||||
return connectionFactory.getConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -229,6 +232,7 @@ public class SingleConnectionFactory extends DelegatingConnectionFactory impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if (method.getName().equals("equals")) {
|
||||
// Only consider equal when proxies are identical.
|
||||
|
||||
@@ -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.
|
||||
@@ -24,6 +24,8 @@ import javax.resource.ResourceException;
|
||||
import javax.resource.cci.Connection;
|
||||
import javax.resource.cci.ConnectionFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* Proxy for a target CCI {@link javax.resource.cci.ConnectionFactory}, adding
|
||||
* awareness of Spring-managed transactions. Similar to a transactional JNDI
|
||||
@@ -91,8 +93,9 @@ public class TransactionAwareConnectionFactoryProxy extends DelegatingConnection
|
||||
*/
|
||||
@Override
|
||||
public Connection getConnection() throws ResourceException {
|
||||
Connection con = ConnectionFactoryUtils.doGetConnection(getTargetConnectionFactory());
|
||||
return getTransactionAwareConnectionProxy(con, getTargetConnectionFactory());
|
||||
ConnectionFactory targetConnectionFactory = obtainTargetConnectionFactory();
|
||||
Connection con = ConnectionFactoryUtils.doGetConnection(targetConnectionFactory);
|
||||
return getTransactionAwareConnectionProxy(con, targetConnectionFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,6 +131,7 @@ public class TransactionAwareConnectionFactoryProxy extends DelegatingConnection
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
// Invocation on Connection interface coming in...
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -75,6 +75,7 @@ public interface CciOperations {
|
||||
* @return the output record
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
@Nullable
|
||||
Record execute(InteractionSpec spec, Record inputRecord) throws DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -106,6 +107,7 @@ public interface CciOperations {
|
||||
* @return the output data extracted with the RecordExtractor object
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
@Nullable
|
||||
<T> T execute(InteractionSpec spec, Record inputRecord, RecordExtractor<T> outputExtractor)
|
||||
throws DataAccessException;
|
||||
|
||||
@@ -118,6 +120,7 @@ public interface CciOperations {
|
||||
* @return the output data extracted with the RecordExtractor object
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
@Nullable
|
||||
<T> T execute(InteractionSpec spec, RecordCreator inputCreator, RecordExtractor<T> outputExtractor)
|
||||
throws DataAccessException;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.jca.cci.core;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.resource.NotSupportedException;
|
||||
import javax.resource.ResourceException;
|
||||
import javax.resource.cci.Connection;
|
||||
@@ -115,22 +114,29 @@ public class CciTemplate implements CciOperations {
|
||||
/**
|
||||
* Set the CCI ConnectionFactory to obtain Connections from.
|
||||
*/
|
||||
public void setConnectionFactory(ConnectionFactory connectionFactory) {
|
||||
public void setConnectionFactory(@Nullable ConnectionFactory connectionFactory) {
|
||||
this.connectionFactory = connectionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the CCI ConnectionFactory used by this template.
|
||||
*/
|
||||
@Nullable
|
||||
public ConnectionFactory getConnectionFactory() {
|
||||
return this.connectionFactory;
|
||||
}
|
||||
|
||||
private ConnectionFactory obtainConnectionFactory() {
|
||||
ConnectionFactory connectionFactory = getConnectionFactory();
|
||||
Assert.state(connectionFactory != null, "No ConnectionFactory set");
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CCI ConnectionSpec that this template instance is
|
||||
* supposed to obtain Connections for.
|
||||
*/
|
||||
public void setConnectionSpec(ConnectionSpec connectionSpec) {
|
||||
public void setConnectionSpec(@Nullable ConnectionSpec connectionSpec) {
|
||||
this.connectionSpec = connectionSpec;
|
||||
}
|
||||
|
||||
@@ -154,7 +160,7 @@ public class CciTemplate implements CciOperations {
|
||||
* @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record)
|
||||
* @see javax.resource.cci.Interaction#execute(javax.resource.cci.InteractionSpec, Record, Record)
|
||||
*/
|
||||
public void setOutputRecordCreator(RecordCreator creator) {
|
||||
public void setOutputRecordCreator(@Nullable RecordCreator creator) {
|
||||
this.outputRecordCreator = creator;
|
||||
}
|
||||
|
||||
@@ -194,9 +200,10 @@ public class CciTemplate implements CciOperations {
|
||||
@Override
|
||||
public <T> T execute(ConnectionCallback<T> action) throws DataAccessException {
|
||||
Assert.notNull(action, "Callback object must not be null");
|
||||
Connection con = ConnectionFactoryUtils.getConnection(getConnectionFactory(), getConnectionSpec());
|
||||
ConnectionFactory connectionFactory = obtainConnectionFactory();
|
||||
Connection con = ConnectionFactoryUtils.getConnection(connectionFactory, getConnectionSpec());
|
||||
try {
|
||||
return action.doInConnection(con, getConnectionFactory());
|
||||
return action.doInConnection(con, connectionFactory);
|
||||
}
|
||||
catch (NotSupportedException ex) {
|
||||
throw new CciOperationNotSupportedException("CCI operation not supported by connector", ex);
|
||||
@@ -242,7 +249,9 @@ public class CciTemplate implements CciOperations {
|
||||
|
||||
@Override
|
||||
public Record execute(InteractionSpec spec, RecordCreator inputCreator) throws DataAccessException {
|
||||
return doExecute(spec, createRecord(inputCreator), null, new SimpleRecordExtractor());
|
||||
Record output = doExecute(spec, createRecord(inputCreator), null, new SimpleRecordExtractor());
|
||||
Assert.state(output != null, "Invalid output record");
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -270,33 +279,30 @@ public class CciTemplate implements CciOperations {
|
||||
* @return the output data extracted with the RecordExtractor object
|
||||
* @throws DataAccessException if there is any problem
|
||||
*/
|
||||
@Nullable
|
||||
protected <T> T doExecute(
|
||||
final InteractionSpec spec, final Record inputRecord, @Nullable final Record outputRecord,
|
||||
@Nullable final RecordExtractor<T> outputExtractor) throws DataAccessException {
|
||||
|
||||
return execute(new InteractionCallback<T>() {
|
||||
@Override
|
||||
public T doInInteraction(Interaction interaction, ConnectionFactory connectionFactory)
|
||||
throws ResourceException, SQLException, DataAccessException {
|
||||
Record outputRecordToUse = outputRecord;
|
||||
try {
|
||||
if (outputRecord != null || getOutputRecordCreator() != null) {
|
||||
// Use the CCI execute method with output record as parameter.
|
||||
if (outputRecord == null) {
|
||||
RecordFactory recordFactory = getRecordFactory(connectionFactory);
|
||||
outputRecordToUse = getOutputRecordCreator().createRecord(recordFactory);
|
||||
}
|
||||
interaction.execute(spec, inputRecord, outputRecordToUse);
|
||||
return execute((InteractionCallback<T>) (interaction, connectionFactory) -> {
|
||||
Record outputRecordToUse = outputRecord;
|
||||
try {
|
||||
if (outputRecord != null || getOutputRecordCreator() != null) {
|
||||
// Use the CCI execute method with output record as parameter.
|
||||
if (outputRecord == null) {
|
||||
RecordFactory recordFactory = getRecordFactory(connectionFactory);
|
||||
outputRecordToUse = getOutputRecordCreator().createRecord(recordFactory);
|
||||
}
|
||||
else {
|
||||
outputRecordToUse = interaction.execute(spec, inputRecord);
|
||||
}
|
||||
return (outputExtractor != null ? outputExtractor.extractData(outputRecordToUse) : null);
|
||||
interaction.execute(spec, inputRecord, outputRecordToUse);
|
||||
}
|
||||
finally {
|
||||
if (outputRecordToUse instanceof ResultSet) {
|
||||
closeResultSet((ResultSet) outputRecordToUse);
|
||||
}
|
||||
else {
|
||||
outputRecordToUse = interaction.execute(spec, inputRecord);
|
||||
}
|
||||
return (outputExtractor != null ? outputExtractor.extractData(outputRecordToUse) : null);
|
||||
}
|
||||
finally {
|
||||
if (outputRecordToUse instanceof ResultSet) {
|
||||
closeResultSet((ResultSet) outputRecordToUse);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -313,7 +319,7 @@ public class CciTemplate implements CciOperations {
|
||||
*/
|
||||
public IndexedRecord createIndexedRecord(String name) throws DataAccessException {
|
||||
try {
|
||||
RecordFactory recordFactory = getRecordFactory(getConnectionFactory());
|
||||
RecordFactory recordFactory = getRecordFactory(obtainConnectionFactory());
|
||||
return recordFactory.createIndexedRecord(name);
|
||||
}
|
||||
catch (NotSupportedException ex) {
|
||||
@@ -334,7 +340,7 @@ public class CciTemplate implements CciOperations {
|
||||
*/
|
||||
public MappedRecord createMappedRecord(String name) throws DataAccessException {
|
||||
try {
|
||||
RecordFactory recordFactory = getRecordFactory(getConnectionFactory());
|
||||
RecordFactory recordFactory = getRecordFactory(obtainConnectionFactory());
|
||||
return recordFactory.createMappedRecord(name);
|
||||
}
|
||||
catch (NotSupportedException ex) {
|
||||
@@ -356,7 +362,7 @@ public class CciTemplate implements CciOperations {
|
||||
*/
|
||||
protected Record createRecord(RecordCreator recordCreator) throws DataAccessException {
|
||||
try {
|
||||
RecordFactory recordFactory = getRecordFactory(getConnectionFactory());
|
||||
RecordFactory recordFactory = getRecordFactory(obtainConnectionFactory());
|
||||
return recordCreator.createRecord(recordFactory);
|
||||
}
|
||||
catch (NotSupportedException ex) {
|
||||
@@ -395,7 +401,7 @@ public class CciTemplate implements CciOperations {
|
||||
* @param interaction the CCI Interaction to close
|
||||
* @see javax.resource.cci.Interaction#close()
|
||||
*/
|
||||
private void closeInteraction(Interaction interaction) {
|
||||
private void closeInteraction(@Nullable Interaction interaction) {
|
||||
if (interaction != null) {
|
||||
try {
|
||||
interaction.close();
|
||||
@@ -416,7 +422,7 @@ public class CciTemplate implements CciOperations {
|
||||
* @param resultSet the CCI ResultSet to close
|
||||
* @see javax.resource.cci.ResultSet#close()
|
||||
*/
|
||||
private void closeResultSet(ResultSet resultSet) {
|
||||
private void closeResultSet(@Nullable ResultSet resultSet) {
|
||||
if (resultSet != null) {
|
||||
try {
|
||||
resultSet.close();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,8 @@ import org.springframework.dao.support.DaoSupport;
|
||||
import org.springframework.jca.cci.CannotGetCciConnectionException;
|
||||
import org.springframework.jca.cci.connection.ConnectionFactoryUtils;
|
||||
import org.springframework.jca.cci.core.CciTemplate;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Convenient super class for CCI-based data access objects.
|
||||
@@ -73,6 +75,7 @@ public abstract class CciDaoSupport extends DaoSupport {
|
||||
/**
|
||||
* Return the ConnectionFactory used by this DAO.
|
||||
*/
|
||||
@Nullable
|
||||
public final ConnectionFactory getConnectionFactory() {
|
||||
return this.cciTemplate.getConnectionFactory();
|
||||
}
|
||||
@@ -122,7 +125,9 @@ public abstract class CciDaoSupport extends DaoSupport {
|
||||
* @see org.springframework.jca.cci.connection.ConnectionFactoryUtils#getConnection(javax.resource.cci.ConnectionFactory)
|
||||
*/
|
||||
protected final Connection getConnection() throws CannotGetCciConnectionException {
|
||||
return ConnectionFactoryUtils.getConnection(getConnectionFactory());
|
||||
ConnectionFactory connectionFactory = getConnectionFactory();
|
||||
Assert.state(connectionFactory != null, "No ConnectionFactory set");
|
||||
return ConnectionFactoryUtils.getConnection(connectionFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -21,6 +21,7 @@ import javax.resource.cci.InteractionSpec;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.jca.cci.core.CciTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base class for EIS operation objects that work with the CCI API.
|
||||
@@ -47,9 +48,7 @@ public abstract class EisOperation implements InitializingBean {
|
||||
* @see #setConnectionFactory
|
||||
*/
|
||||
public void setCciTemplate(CciTemplate cciTemplate) {
|
||||
if (cciTemplate == null) {
|
||||
throw new IllegalArgumentException("cciTemplate must not be null");
|
||||
}
|
||||
Assert.notNull(cciTemplate, "CciTemplate must not be null");
|
||||
this.cciTemplate = cciTemplate;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,7 @@ import javax.resource.cci.RecordFactory;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jca.cci.core.RecordCreator;
|
||||
import org.springframework.jca.cci.core.RecordExtractor;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* EIS operation object that expects mapped input and output objects,
|
||||
@@ -85,6 +86,7 @@ public abstract class MappingRecordOperation extends EisOperation {
|
||||
* @see #createInputRecord
|
||||
* @see #extractOutputData
|
||||
*/
|
||||
@Nullable
|
||||
public Object execute(Object inputObject) throws DataAccessException {
|
||||
return getCciTemplate().execute(
|
||||
getInteractionSpec(), new RecordCreatorImpl(inputObject), new RecordExtractorImpl());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ import javax.resource.spi.BootstrapContext;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* {@link org.springframework.beans.factory.config.BeanPostProcessor}
|
||||
@@ -41,7 +42,7 @@ class BootstrapContextAwareProcessor implements BeanPostProcessor {
|
||||
/**
|
||||
* Create a new BootstrapContextAwareProcessor for the given context.
|
||||
*/
|
||||
public BootstrapContextAwareProcessor(BootstrapContext bootstrapContext) {
|
||||
public BootstrapContextAwareProcessor(@Nullable BootstrapContext bootstrapContext) {
|
||||
this.bootstrapContext = bootstrapContext;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -177,15 +177,17 @@ public class SpringContextResourceAdapter implements ResourceAdapter {
|
||||
protected ConfigurableApplicationContext createApplicationContext(BootstrapContext bootstrapContext) {
|
||||
ResourceAdapterApplicationContext applicationContext =
|
||||
new ResourceAdapterApplicationContext(bootstrapContext);
|
||||
|
||||
// Set ResourceAdapter's ClassLoader as bean class loader.
|
||||
applicationContext.setClassLoader(getClass().getClassLoader());
|
||||
|
||||
// Extract individual config locations.
|
||||
String[] configLocations =
|
||||
StringUtils.tokenizeToStringArray(getContextConfigLocation(), CONFIG_LOCATION_DELIMITERS);
|
||||
if (configLocations != null) {
|
||||
loadBeanDefinitions(applicationContext, configLocations);
|
||||
}
|
||||
|
||||
loadBeanDefinitions(applicationContext, configLocations);
|
||||
applicationContext.refresh();
|
||||
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -311,7 +311,7 @@ public abstract class AbstractMessageEndpointFactory implements MessageEndpointF
|
||||
|
||||
private boolean rollbackOnly;
|
||||
|
||||
public TransactionDelegate(XAResource xaResource) {
|
||||
public TransactionDelegate(@Nullable XAResource xaResource) {
|
||||
if (xaResource == null) {
|
||||
if (transactionFactory != null && !transactionFactory.supportsResourceAdapterManagedTransactions()) {
|
||||
throw new IllegalStateException("ResourceAdapter-provided XAResource is required for " +
|
||||
|
||||
@@ -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.
|
||||
@@ -24,6 +24,8 @@ import javax.resource.spi.endpoint.MessageEndpointFactory;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Generic bean that manages JCA 1.7 message endpoints within a Spring
|
||||
@@ -171,6 +173,7 @@ public class GenericMessageEndpointManager implements SmartLifecycle, Initializi
|
||||
/**
|
||||
* Return the JCA ResourceAdapter to manage endpoints for.
|
||||
*/
|
||||
@Nullable
|
||||
public ResourceAdapter getResourceAdapter() {
|
||||
return this.resourceAdapter;
|
||||
}
|
||||
@@ -190,6 +193,7 @@ public class GenericMessageEndpointManager implements SmartLifecycle, Initializi
|
||||
/**
|
||||
* Return the JCA MessageEndpointFactory to activate.
|
||||
*/
|
||||
@Nullable
|
||||
public MessageEndpointFactory getMessageEndpointFactory() {
|
||||
return this.messageEndpointFactory;
|
||||
}
|
||||
@@ -206,6 +210,7 @@ public class GenericMessageEndpointManager implements SmartLifecycle, Initializi
|
||||
/**
|
||||
* Return the JCA ActivationSpec to use for activating the endpoint.
|
||||
*/
|
||||
@Nullable
|
||||
public ActivationSpec getActivationSpec() {
|
||||
return this.activationSpec;
|
||||
}
|
||||
@@ -281,8 +286,10 @@ public class GenericMessageEndpointManager implements SmartLifecycle, Initializi
|
||||
public void start() {
|
||||
synchronized (this.lifecycleMonitor) {
|
||||
if (!this.running) {
|
||||
ResourceAdapter resourceAdapter = getResourceAdapter();
|
||||
Assert.state(resourceAdapter != null, "No ResourceAdapter set");
|
||||
try {
|
||||
getResourceAdapter().endpointActivation(getMessageEndpointFactory(), getActivationSpec());
|
||||
resourceAdapter.endpointActivation(getMessageEndpointFactory(), getActivationSpec());
|
||||
}
|
||||
catch (ResourceException ex) {
|
||||
throw new IllegalStateException("Could not activate message endpoint", ex);
|
||||
@@ -299,7 +306,9 @@ public class GenericMessageEndpointManager implements SmartLifecycle, Initializi
|
||||
public void stop() {
|
||||
synchronized (this.lifecycleMonitor) {
|
||||
if (this.running) {
|
||||
getResourceAdapter().endpointDeactivation(getMessageEndpointFactory(), getActivationSpec());
|
||||
ResourceAdapter resourceAdapter = getResourceAdapter();
|
||||
Assert.state(resourceAdapter != null, "No ResourceAdapter set");
|
||||
resourceAdapter.endpointDeactivation(getMessageEndpointFactory(), getActivationSpec());
|
||||
this.running = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -141,9 +141,8 @@ public class SimpleTaskWorkManager implements WorkManager {
|
||||
* (or -1 if not applicable or not known)
|
||||
* @throws WorkException if the TaskExecutor did not accept the Work
|
||||
*/
|
||||
protected long executeWork(TaskExecutor taskExecutor, Work work, long startTimeout,
|
||||
boolean blockUntilStarted, ExecutionContext executionContext, WorkListener workListener)
|
||||
throws WorkException {
|
||||
protected long executeWork(TaskExecutor taskExecutor, Work work, long startTimeout, boolean blockUntilStarted,
|
||||
@Nullable ExecutionContext executionContext, @Nullable WorkListener workListener) throws WorkException {
|
||||
|
||||
if (executionContext != null && executionContext.getXid() != null) {
|
||||
throw new WorkException("SimpleTaskWorkManager does not supported imported XIDs: " + executionContext.getXid());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -86,7 +86,7 @@ public class TransactionSystemException extends TransactionException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Class<?> exType) {
|
||||
public boolean contains(@Nullable Class<?> exType) {
|
||||
return super.contains(exType) || (exType != null && exType.isInstance(this.applicationException));
|
||||
}
|
||||
|
||||
|
||||
@@ -141,14 +141,14 @@ public abstract class AbstractFallbackTransactionAttributeSource implements Tran
|
||||
* @see #getTransactionAttribute
|
||||
*/
|
||||
@Nullable
|
||||
protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
|
||||
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
|
||||
// Don't allow no-public methods as required.
|
||||
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ignore CGLIB subclasses - introspect the actual user class.
|
||||
Class<?> userClass = ClassUtils.getUserClass(targetClass);
|
||||
Class<?> userClass = (targetClass != null ? ClassUtils.getUserClass(targetClass) : null);
|
||||
// The method may be on an interface, but we need attributes from the target class.
|
||||
// If the target class is null, the method will be unchanged.
|
||||
Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -54,7 +54,7 @@ public class MatchAlwaysTransactionAttributeSource implements TransactionAttribu
|
||||
|
||||
@Override
|
||||
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
|
||||
return (method == null || ClassUtils.isUserLevelMethod(method) ? this.transactionAttribute : null);
|
||||
return (ClassUtils.isUserLevelMethod(method) ? this.transactionAttribute : null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -59,8 +59,7 @@ public class MethodMapTransactionAttributeSource
|
||||
private boolean initialized = false;
|
||||
|
||||
/** Map from Method to TransactionAttribute */
|
||||
private final Map<Method, TransactionAttribute> transactionAttributeMap =
|
||||
new HashMap<>();
|
||||
private final Map<Method, TransactionAttribute> transactionAttributeMap = new HashMap<>();
|
||||
|
||||
/** Map from Method to name pattern used for registration */
|
||||
private final Map<Method, String> methodNameMap = new HashMap<>();
|
||||
@@ -83,7 +82,7 @@ public class MethodMapTransactionAttributeSource
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(@Nullable ClassLoader beanClassLoader) {
|
||||
public void setBeanClassLoader(ClassLoader beanClassLoader) {
|
||||
this.beanClassLoader = beanClassLoader;
|
||||
}
|
||||
|
||||
@@ -105,7 +104,7 @@ public class MethodMapTransactionAttributeSource
|
||||
* @param methodMap Map from method names to {@code TransactionAttribute} instances
|
||||
* @see #setMethodMap
|
||||
*/
|
||||
protected void initMethodMap(Map<String, TransactionAttribute> methodMap) {
|
||||
protected void initMethodMap(@Nullable Map<String, TransactionAttribute> methodMap) {
|
||||
if (methodMap != null) {
|
||||
for (Map.Entry<String, TransactionAttribute> entry : methodMap.entrySet()) {
|
||||
addTransactionalMethod(entry.getKey(), entry.getValue());
|
||||
|
||||
@@ -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.
|
||||
@@ -35,6 +35,7 @@ import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.TransactionSystemException;
|
||||
import org.springframework.transaction.support.CallbackPreferringPlatformTransactionManager;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -200,7 +201,7 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
* @see NameMatchTransactionAttributeSource
|
||||
* @see org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
|
||||
*/
|
||||
public void setTransactionAttributeSources(TransactionAttributeSource[] transactionAttributeSources) {
|
||||
public void setTransactionAttributeSources(TransactionAttributeSource... transactionAttributeSources) {
|
||||
this.transactionAttributeSource = new CompositeTransactionAttributeSource(transactionAttributeSources);
|
||||
}
|
||||
|
||||
@@ -220,6 +221,7 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
/**
|
||||
* Return the transaction attribute source.
|
||||
*/
|
||||
@Nullable
|
||||
public TransactionAttributeSource getTransactionAttributeSource() {
|
||||
return this.transactionAttributeSource;
|
||||
}
|
||||
@@ -268,11 +270,12 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
* @throws Throwable propagated from the target invocation
|
||||
*/
|
||||
@Nullable
|
||||
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
|
||||
throws Throwable {
|
||||
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
|
||||
final InvocationCallback invocation) throws Throwable {
|
||||
|
||||
// If the transaction attribute is null, the method is non-transactional.
|
||||
final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
|
||||
TransactionAttributeSource tas = getTransactionAttributeSource();
|
||||
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
|
||||
final PlatformTransactionManager tm = determineTransactionManager(txAttr);
|
||||
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
|
||||
|
||||
@@ -354,11 +357,13 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
/**
|
||||
* Determine the specific transaction manager to use for the given transaction.
|
||||
*/
|
||||
protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr) {
|
||||
@Nullable
|
||||
protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
|
||||
// Do not attempt to lookup tx manager if no tx attributes are set
|
||||
if (txAttr == null || this.beanFactory == null) {
|
||||
return getTransactionManager();
|
||||
}
|
||||
|
||||
String qualifier = txAttr.getQualifier();
|
||||
if (StringUtils.hasText(qualifier)) {
|
||||
return determineQualifiedTransactionManager(qualifier);
|
||||
@@ -390,7 +395,9 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
return txManager;
|
||||
}
|
||||
|
||||
private String methodIdentification(Method method, Class<?> targetClass, TransactionAttribute txAttr) {
|
||||
private String methodIdentification(Method method, @Nullable Class<?> targetClass,
|
||||
@Nullable TransactionAttribute txAttr) {
|
||||
|
||||
String methodIdentification = methodIdentification(method, targetClass);
|
||||
if (methodIdentification == null) {
|
||||
if (txAttr instanceof DefaultTransactionAttribute) {
|
||||
@@ -416,7 +423,7 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
* @see org.springframework.util.ClassUtils#getQualifiedMethodName
|
||||
*/
|
||||
@Nullable
|
||||
protected String methodIdentification(Method method, Class<?> targetClass) {
|
||||
protected String methodIdentification(Method method, @Nullable Class<?> targetClass) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -433,8 +440,8 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
* @see #getTransactionAttributeSource()
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
protected TransactionInfo createTransactionIfNecessary(
|
||||
PlatformTransactionManager tm, @Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
|
||||
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
|
||||
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
|
||||
|
||||
// If no name specified, apply method identification as transaction name.
|
||||
if (txAttr != null && txAttr.getName() == null) {
|
||||
@@ -469,8 +476,9 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
* @param status the TransactionStatus for the current transaction
|
||||
* @return the prepared TransactionInfo object
|
||||
*/
|
||||
protected TransactionInfo prepareTransactionInfo(PlatformTransactionManager tm,
|
||||
@Nullable TransactionAttribute txAttr, String joinpointIdentification, TransactionStatus status) {
|
||||
protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
|
||||
@Nullable TransactionAttribute txAttr, String joinpointIdentification,
|
||||
@Nullable TransactionStatus status) {
|
||||
|
||||
TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
|
||||
if (txAttr != null) {
|
||||
@@ -501,7 +509,7 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
* Do nothing if we didn't create a transaction.
|
||||
* @param txInfo information about the current transaction
|
||||
*/
|
||||
protected void commitTransactionAfterReturning(TransactionInfo txInfo) {
|
||||
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
|
||||
if (txInfo != null && txInfo.hasTransaction()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
|
||||
@@ -516,13 +524,13 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
* @param txInfo information about the current transaction
|
||||
* @param ex throwable encountered
|
||||
*/
|
||||
protected void completeTransactionAfterThrowing(TransactionInfo txInfo, Throwable ex) {
|
||||
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
|
||||
if (txInfo != null && txInfo.hasTransaction()) {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
|
||||
"] after exception: " + ex);
|
||||
}
|
||||
if (txInfo.transactionAttribute.rollbackOn(ex)) {
|
||||
if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
|
||||
try {
|
||||
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
|
||||
}
|
||||
@@ -591,8 +599,8 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
|
||||
private TransactionInfo oldTransactionInfo;
|
||||
|
||||
public TransactionInfo(PlatformTransactionManager transactionManager,
|
||||
TransactionAttribute transactionAttribute, String joinpointIdentification) {
|
||||
public TransactionInfo(@Nullable PlatformTransactionManager transactionManager,
|
||||
@Nullable TransactionAttribute transactionAttribute, String joinpointIdentification) {
|
||||
|
||||
this.transactionManager = transactionManager;
|
||||
this.transactionAttribute = transactionAttribute;
|
||||
@@ -600,9 +608,11 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
}
|
||||
|
||||
public PlatformTransactionManager getTransactionManager() {
|
||||
Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");
|
||||
return this.transactionManager;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TransactionAttribute getTransactionAttribute() {
|
||||
return this.transactionAttribute;
|
||||
}
|
||||
@@ -615,7 +625,7 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
return this.joinpointIdentification;
|
||||
}
|
||||
|
||||
public void newTransactionStatus(TransactionStatus status) {
|
||||
public void newTransactionStatus(@Nullable TransactionStatus status) {
|
||||
this.transactionStatus = status;
|
||||
}
|
||||
|
||||
@@ -646,7 +656,7 @@ public abstract class TransactionAspectSupport implements BeanFactoryAware, Init
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.transactionAttribute.toString();
|
||||
return (this.transactionAttribute != null ? this.transactionAttribute.toString() : "No transaction");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -38,8 +38,8 @@ public interface TransactionAttributeSource {
|
||||
* Return the transaction attribute for the given method,
|
||||
* or {@code null} if the method is non-transactional.
|
||||
* @param method the method to introspect
|
||||
* @param targetClass the target class. May be {@code null},
|
||||
* in which case the declaring class of the method must be used.
|
||||
* @param targetClass the target class (may be {@code null},
|
||||
* in which case the declaring class of the method must be used)
|
||||
* @return TransactionAttribute the matching transaction attribute,
|
||||
* or {@code null} if none found
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,7 +35,7 @@ abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPoi
|
||||
|
||||
@Override
|
||||
public boolean matches(Method method, @Nullable Class<?> targetClass) {
|
||||
if (TransactionalProxy.class.isAssignableFrom(targetClass)) {
|
||||
if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
|
||||
return false;
|
||||
}
|
||||
TransactionAttributeSource tas = getTransactionAttributeSource();
|
||||
|
||||
@@ -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.
|
||||
@@ -21,7 +21,6 @@ import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.transaction.HeuristicMixedException;
|
||||
import javax.transaction.HeuristicRollbackException;
|
||||
@@ -251,6 +250,7 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager
|
||||
/**
|
||||
* Return the JNDI environment to use for JNDI lookups.
|
||||
*/
|
||||
@Nullable
|
||||
public Properties getJndiEnvironment() {
|
||||
return this.jndiTemplate.getEnvironment();
|
||||
}
|
||||
@@ -270,6 +270,7 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager
|
||||
/**
|
||||
* Return the JTA UserTransaction that this transaction manager uses.
|
||||
*/
|
||||
@Nullable
|
||||
public UserTransaction getUserTransaction() {
|
||||
return this.userTransaction;
|
||||
}
|
||||
@@ -958,7 +959,7 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doResume(Object transaction, Object suspendedResources) {
|
||||
protected void doResume(@Nullable Object transaction, Object suspendedResources) {
|
||||
JtaTransactionObject txObject = (JtaTransactionObject) transaction;
|
||||
try {
|
||||
doJtaResume(txObject, suspendedResources);
|
||||
@@ -984,7 +985,7 @@ public class JtaTransactionManager extends AbstractPlatformTransactionManager
|
||||
* @see #getTransactionManager()
|
||||
* @see javax.transaction.TransactionManager#resume(javax.transaction.Transaction)
|
||||
*/
|
||||
protected void doJtaResume(JtaTransactionObject txObject, Object suspendedTransaction)
|
||||
protected void doJtaResume(@Nullable JtaTransactionObject txObject, Object suspendedTransaction)
|
||||
throws InvalidTransactionException, SystemException {
|
||||
|
||||
if (getTransactionManager() == null) {
|
||||
|
||||
@@ -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.
|
||||
@@ -64,9 +64,6 @@ public class JtaTransactionObject implements SmartTransactionObject {
|
||||
*/
|
||||
@Override
|
||||
public boolean isRollbackOnly() {
|
||||
if (this.userTransaction == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
int jtaStatus = this.userTransaction.getStatus();
|
||||
return (jtaStatus == Status.STATUS_MARKED_ROLLBACK || jtaStatus == Status.STATUS_ROLLEDBACK);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,6 +24,7 @@ import javax.transaction.UserTransaction;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -76,8 +77,8 @@ public class SpringJtaSynchronizationAdapter implements Synchronization {
|
||||
* (can be omitted if the JTA provider itself marks the transaction rollback-only
|
||||
* in such a scenario, which is required by the JTA specification as of JTA 1.1).
|
||||
*/
|
||||
public SpringJtaSynchronizationAdapter(
|
||||
TransactionSynchronization springSynchronization, UserTransaction jtaUserTransaction) {
|
||||
public SpringJtaSynchronizationAdapter(TransactionSynchronization springSynchronization,
|
||||
@Nullable UserTransaction jtaUserTransaction) {
|
||||
|
||||
this(springSynchronization);
|
||||
if (jtaUserTransaction != null && !jtaUserTransaction.getClass().getName().startsWith("weblogic.")) {
|
||||
@@ -99,7 +100,7 @@ public class SpringJtaSynchronizationAdapter implements Synchronization {
|
||||
* in such a scenario, which is required by the JTA specification as of JTA 1.1)
|
||||
*/
|
||||
public SpringJtaSynchronizationAdapter(
|
||||
TransactionSynchronization springSynchronization, TransactionManager jtaTransactionManager) {
|
||||
TransactionSynchronization springSynchronization, @Nullable TransactionManager jtaTransactionManager) {
|
||||
|
||||
this(springSynchronization);
|
||||
if (jtaTransactionManager != null && !jtaTransactionManager.getClass().getName().startsWith("weblogic.")) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -29,6 +29,7 @@ import javax.transaction.UserTransaction;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.transaction.TransactionDefinition;
|
||||
import org.springframework.transaction.TransactionSystemException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Special {@link JtaTransactionManager} variant for BEA WebLogic (9.0 and higher).
|
||||
@@ -198,6 +199,12 @@ public class WebLogicJtaTransactionManager extends JtaTransactionManager {
|
||||
}
|
||||
}
|
||||
|
||||
private TransactionManager obtainTransactionManager() {
|
||||
TransactionManager tm = getTransactionManager();
|
||||
Assert.state(tm != null, "No TransactionManager set");
|
||||
return tm;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void doJtaBegin(JtaTransactionObject txObject, TransactionDefinition definition)
|
||||
@@ -243,7 +250,7 @@ public class WebLogicJtaTransactionManager extends JtaTransactionManager {
|
||||
if (this.weblogicTransactionManagerAvailable) {
|
||||
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
|
||||
try {
|
||||
Transaction tx = getTransactionManager().getTransaction();
|
||||
Transaction tx = obtainTransactionManager().getTransaction();
|
||||
Integer isolationLevel = definition.getIsolationLevel();
|
||||
/*
|
||||
weblogic.transaction.Transaction wtx = (weblogic.transaction.Transaction) tx;
|
||||
@@ -271,7 +278,7 @@ public class WebLogicJtaTransactionManager extends JtaTransactionManager {
|
||||
throws InvalidTransactionException, SystemException {
|
||||
|
||||
try {
|
||||
getTransactionManager().resume((Transaction) suspendedTransaction);
|
||||
obtainTransactionManager().resume((Transaction) suspendedTransaction);
|
||||
}
|
||||
catch (InvalidTransactionException ex) {
|
||||
if (!this.weblogicTransactionManagerAvailable) {
|
||||
@@ -330,7 +337,7 @@ public class WebLogicJtaTransactionManager extends JtaTransactionManager {
|
||||
catch (Exception ex) {
|
||||
throw new SystemException("Could not invoke WebLogic's UserTransaction.begin() method: " + ex);
|
||||
}
|
||||
return new ManagedTransactionAdapter(getTransactionManager());
|
||||
return new ManagedTransactionAdapter(obtainTransactionManager());
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
@@ -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.
|
||||
@@ -26,6 +26,7 @@ import com.ibm.wsspi.uow.UOWException;
|
||||
import com.ibm.wsspi.uow.UOWManager;
|
||||
import com.ibm.wsspi.uow.UOWManagerFactory;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.transaction.IllegalTransactionStateException;
|
||||
import org.springframework.transaction.InvalidTimeoutException;
|
||||
import org.springframework.transaction.NestedTransactionNotSupportedException;
|
||||
@@ -219,7 +220,9 @@ public class WebSphereUowTransactionManager extends JtaTransactionManager
|
||||
|
||||
|
||||
@Override
|
||||
public <T> T execute(TransactionDefinition definition, TransactionCallback<T> callback) throws TransactionException {
|
||||
public <T> T execute(@Nullable TransactionDefinition definition, TransactionCallback<T> callback)
|
||||
throws TransactionException {
|
||||
|
||||
if (definition == null) {
|
||||
// Use defaults if no transaction definition given.
|
||||
definition = new DefaultTransactionDefinition();
|
||||
|
||||
@@ -511,7 +511,7 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran
|
||||
* Create a TransactionStatus instance for the given arguments.
|
||||
*/
|
||||
protected DefaultTransactionStatus newTransactionStatus(
|
||||
TransactionDefinition definition, Object transaction, boolean newTransaction,
|
||||
TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
|
||||
boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {
|
||||
|
||||
boolean actualNewSynchronization = newSynchronization &&
|
||||
@@ -633,7 +633,7 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran
|
||||
* Resume outer transaction after inner transaction begin failed.
|
||||
*/
|
||||
private void resumeAfterBeginException(
|
||||
Object transaction, SuspendedResourcesHolder suspendedResources, Throwable beginEx) {
|
||||
Object transaction, @Nullable SuspendedResourcesHolder suspendedResources, Throwable beginEx) {
|
||||
|
||||
String exMessage = "Inner transaction begin exception overridden by outer transaction resume exception";
|
||||
try {
|
||||
@@ -1006,7 +1006,8 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran
|
||||
if (status.isDebug()) {
|
||||
logger.debug("Resuming suspended transaction after completion of inner transaction");
|
||||
}
|
||||
resume(status.getTransaction(), (SuspendedResourcesHolder) status.getSuspendedResources());
|
||||
Object transaction = (status.hasTransaction() ? status.getTransaction() : null);
|
||||
resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1129,7 +1130,7 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran
|
||||
* @throws TransactionException in case of system errors
|
||||
* @see #doSuspend
|
||||
*/
|
||||
protected void doResume(Object transaction, Object suspendedResources) throws TransactionException {
|
||||
protected void doResume(@Nullable Object transaction, Object suspendedResources) throws TransactionException {
|
||||
throw new TransactionSuspensionNotSupportedException(
|
||||
"Transaction manager [" + getClass().getName() + "] does not support transaction suspension");
|
||||
}
|
||||
@@ -1287,8 +1288,9 @@ public abstract class AbstractPlatformTransactionManager implements PlatformTran
|
||||
}
|
||||
|
||||
private SuspendedResourcesHolder(
|
||||
Object suspendedResources, List<TransactionSynchronization> suspendedSynchronizations,
|
||||
String name, boolean readOnly, Integer isolationLevel, boolean wasActive) {
|
||||
@Nullable Object suspendedResources, List<TransactionSynchronization> suspendedSynchronizations,
|
||||
@Nullable String name, boolean readOnly, @Nullable Integer isolationLevel, boolean wasActive) {
|
||||
|
||||
this.suspendedResources = suspendedResources;
|
||||
this.suspendedSynchronizations = suspendedSynchronizations;
|
||||
this.name = name;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -151,12 +151,13 @@ public abstract class AbstractTransactionStatus implements TransactionStatus {
|
||||
* and release the savepoint right afterwards.
|
||||
*/
|
||||
public void rollbackToHeldSavepoint() throws TransactionException {
|
||||
if (!hasSavepoint()) {
|
||||
Object savepoint = getSavepoint();
|
||||
if (savepoint == null) {
|
||||
throw new TransactionUsageException(
|
||||
"Cannot roll back to savepoint - no savepoint associated with current transaction");
|
||||
}
|
||||
getSavepointManager().rollbackToSavepoint(getSavepoint());
|
||||
getSavepointManager().releaseSavepoint(getSavepoint());
|
||||
getSavepointManager().rollbackToSavepoint(savepoint);
|
||||
getSavepointManager().releaseSavepoint(savepoint);
|
||||
setSavepoint(null);
|
||||
}
|
||||
|
||||
@@ -164,11 +165,12 @@ public abstract class AbstractTransactionStatus implements TransactionStatus {
|
||||
* Release the savepoint that is held for the transaction.
|
||||
*/
|
||||
public void releaseHeldSavepoint() throws TransactionException {
|
||||
if (!hasSavepoint()) {
|
||||
Object savepoint = getSavepoint();
|
||||
if (savepoint == null) {
|
||||
throw new TransactionUsageException(
|
||||
"Cannot release savepoint - no savepoint associated with current transaction");
|
||||
}
|
||||
getSavepointManager().releaseSavepoint(getSavepoint());
|
||||
getSavepointManager().releaseSavepoint(savepoint);
|
||||
setSavepoint(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -55,7 +55,7 @@ public interface CallbackPreferringPlatformTransactionManager extends PlatformTr
|
||||
* @throws RuntimeException if thrown by the TransactionCallback
|
||||
*/
|
||||
@Nullable
|
||||
<T> T execute(TransactionDefinition definition, TransactionCallback<T> callback)
|
||||
<T> T execute(@Nullable TransactionDefinition definition, TransactionCallback<T> callback)
|
||||
throws TransactionException;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -114,7 +114,7 @@ public class DefaultTransactionDefinition implements TransactionDefinition, Seri
|
||||
* @see #PROPAGATION_REQUIRED
|
||||
*/
|
||||
public final void setPropagationBehaviorName(String constantName) throws IllegalArgumentException {
|
||||
if (constantName == null || !constantName.startsWith(PREFIX_PROPAGATION)) {
|
||||
if (!constantName.startsWith(PREFIX_PROPAGATION)) {
|
||||
throw new IllegalArgumentException("Only propagation constants allowed");
|
||||
}
|
||||
setPropagationBehavior(constants.asNumber(constantName).intValue());
|
||||
@@ -149,7 +149,7 @@ public class DefaultTransactionDefinition implements TransactionDefinition, Seri
|
||||
* @see #ISOLATION_DEFAULT
|
||||
*/
|
||||
public final void setIsolationLevelName(String constantName) throws IllegalArgumentException {
|
||||
if (constantName == null || !constantName.startsWith(PREFIX_ISOLATION)) {
|
||||
if (!constantName.startsWith(PREFIX_ISOLATION)) {
|
||||
throw new IllegalArgumentException("Only isolation constants allowed");
|
||||
}
|
||||
setIsolationLevel(constants.asNumber(constantName).intValue());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.transaction.support;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.transaction.NestedTransactionNotSupportedException;
|
||||
import org.springframework.transaction.SavepointManager;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Default implementation of the {@link org.springframework.transaction.TransactionStatus}
|
||||
@@ -78,7 +79,7 @@ public class DefaultTransactionStatus extends AbstractTransactionStatus {
|
||||
* for this transaction, if any
|
||||
*/
|
||||
public DefaultTransactionStatus(
|
||||
Object transaction, boolean newTransaction, boolean newSynchronization,
|
||||
@Nullable Object transaction, boolean newTransaction, boolean newSynchronization,
|
||||
boolean readOnly, boolean debug, @Nullable Object suspendedResources) {
|
||||
|
||||
this.transaction = transaction;
|
||||
@@ -92,8 +93,10 @@ public class DefaultTransactionStatus extends AbstractTransactionStatus {
|
||||
|
||||
/**
|
||||
* Return the underlying transaction object.
|
||||
* @throws IllegalStateException if no transaction is active
|
||||
*/
|
||||
public Object getTransaction() {
|
||||
Assert.state(this.transaction != null, "No transaction active");
|
||||
return this.transaction;
|
||||
}
|
||||
|
||||
@@ -177,11 +180,12 @@ public class DefaultTransactionStatus extends AbstractTransactionStatus {
|
||||
*/
|
||||
@Override
|
||||
protected SavepointManager getSavepointManager() {
|
||||
if (!isTransactionSavepointManager()) {
|
||||
Object transaction = this.transaction;
|
||||
if (!(transaction instanceof SavepointManager)) {
|
||||
throw new NestedTransactionNotSupportedException(
|
||||
"Transaction object [" + getTransaction() + "] does not support savepoints");
|
||||
"Transaction object [" + this.transaction + "] does not support savepoints");
|
||||
}
|
||||
return (SavepointManager) getTransaction();
|
||||
return (SavepointManager) transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,7 +195,7 @@ public class DefaultTransactionStatus extends AbstractTransactionStatus {
|
||||
* @see org.springframework.transaction.SavepointManager
|
||||
*/
|
||||
public boolean isTransactionSavepointManager() {
|
||||
return (getTransaction() instanceof SavepointManager);
|
||||
return (this.transaction instanceof SavepointManager);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -22,6 +22,7 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.config.Scope;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A simple transaction-backed {@link Scope} implementation, delegating to
|
||||
@@ -52,6 +53,7 @@ public class SimpleTransactionScope implements Scope {
|
||||
Object scopedObject = scopedObjects.scopedInstances.get(name);
|
||||
if (scopedObject == null) {
|
||||
scopedObject = objectFactory.getObject();
|
||||
Assert.state(scopedObject != null, "Scoped object resolved to null");
|
||||
scopedObjects.scopedInstances.put(name, scopedObject);
|
||||
}
|
||||
return scopedObject;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,6 +23,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.aop.scope.ScopedObject;
|
||||
import org.springframework.core.InfrastructureProxy;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
@@ -127,7 +128,7 @@ public abstract class TransactionSynchronizationUtils {
|
||||
* @param synchronizations List of TransactionSynchronization objects
|
||||
* @see TransactionSynchronization#afterCommit()
|
||||
*/
|
||||
public static void invokeAfterCommit(List<TransactionSynchronization> synchronizations) {
|
||||
public static void invokeAfterCommit(@Nullable List<TransactionSynchronization> synchronizations) {
|
||||
if (synchronizations != null) {
|
||||
for (TransactionSynchronization synchronization : synchronizations) {
|
||||
synchronization.afterCommit();
|
||||
@@ -161,7 +162,9 @@ public abstract class TransactionSynchronizationUtils {
|
||||
* @see TransactionSynchronization#STATUS_ROLLED_BACK
|
||||
* @see TransactionSynchronization#STATUS_UNKNOWN
|
||||
*/
|
||||
public static void invokeAfterCompletion(List<TransactionSynchronization> synchronizations, int completionStatus) {
|
||||
public static void invokeAfterCompletion(@Nullable List<TransactionSynchronization> synchronizations,
|
||||
int completionStatus) {
|
||||
|
||||
if (synchronizations != null) {
|
||||
for (TransactionSynchronization synchronization : synchronizations) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user