Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright 2002-2008 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.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.springframework.batch.item.database;
 
 
 
Implementation of org.springframework.jdbc.datasource.SmartDataSource that is capable of keeping a single JDBC Connection which is NOT closed after each use even if java.sql.Connection.close() is called. The connection can be kept open over multiple transactions when used together with any of Spring's org.springframework.transaction.PlatformTransactionManager implementations.

Loosely based on the SingleConnectionDataSource implementation in Spring Core. Intended to be used with the JdbcCursorItemReader to provide a connection that remains open across transaction boundaries, It remains open for the life of the cursor, and can be shared with the main transaction of the rest of the step processing.

Once close suppression has been turned on for a connection, it will be returned for the first getConnection() call. Any subsequent calls to getConnection() will retrieve a new connection from the wrapped javax.sql.DataSource until the org.springframework.jdbc.datasource.DataSourceUtils queries whether the connection should be closed or not by calling shouldClose(java.sql.Connection) for the close-suppressed java.sql.Connection. At that point the cycle starts over again, and the next getConnection() call will have the java.sql.Connection that is being close-suppressed returned. This allows the use of the close-suppressed java.sql.Connection to be the main java.sql.Connection for an extended data access process. The close suppression is turned off by calling stopCloseSuppression(java.sql.Connection).

This class is not multi-threading capable.

The connection returned will be a close-suppressing proxy instead of the physical java.sql.Connection. Be aware that you will not be able to cast this to a native OracleConnection or the like anymore; you need to use a org.springframework.jdbc.support.nativejdbc.NativeJdbcExtractor.

 
Provided DataSource
 
 	private DataSource dataSource;

The connection to suppress close calls for
 
 	private Connection closeSuppressedConnection = null;

The connection to suppress close calls for
 
 	private boolean borrowedConnection = false;

Synchronization monitor for the shared Connection
 
 	private final Object connectionMonitor = new Object();

No arg constructor for use when configured using JavaBean style.
 
	}

Constructor that takes as a parameter with the {&link DataSource} to be wrapped.
		this. = dataSource;
	}

Setter for the {&link DataSource} that is to be wrapped.

Parameters:
dataSource the DataSource
	public void setDataSource(DataSource dataSource) {
		this. = dataSource;
	}

	public boolean shouldClose(Connection connection) {
		boolean shouldClose = !isCloseSuppressionActive(connection);
		}
		return shouldClose;
	}

Return the status of close suppression being activated for a given java.sql.Connection

Parameters:
connection the java.sql.Connection that the close suppression status is requested for
Returns:
true or false
	public boolean isCloseSuppressionActive(Connection connection) {
		if (connection == null) {
			return false;
		}
		return connection.equals() ? true : false;
	}

Parameters:
connection the java.sql.Connection that close suppression is requested for
	public void startCloseSuppression(Connection connection) {
		synchronized (this.) {
			if (TransactionSynchronizationManager.isActualTransactionActive()) {
			}
		}
	}

Parameters:
connection the java.sql.Connection that close suppression should be turned off for
	public void stopCloseSuppression(Connection connection) {
		synchronized (this.) {
		}
	}
	public Connection getConnection() throws SQLException {
		synchronized (this.) {
			return initConnection(nullnull);
		}
	}
	public Connection getConnection(String usernameString passwordthrows SQLException {
		synchronized (this.) {
			return initConnection(usernamepassword);
		}
	}
	private boolean completeCloseCall(Connection connection) {
		}
		return isCloseSuppressionActive(connection);
	}
	private Connection initConnection(String usernameString passwordthrows SQLException {
		if ( != null) {
			}
		}
		Connection target;
		if (username != null) {
			target = .getConnection(usernamepassword);
		}
		else {
		}
		return connection;
	}
	public PrintWriter getLogWriter() throws SQLException {
	}
	public int getLoginTimeout() throws SQLException {
	}
	public void setLogWriter(PrintWriter outthrows SQLException {
	}
	public void setLoginTimeout(int secondsthrows SQLException {
	}

Wrap the given Connection with a proxy that delegates every method call to it but suppresses close calls.

Parameters:
target the original Connection to wrap
Returns:
the wrapped Connection
				new Class[] { ConnectionProxy.class }, new CloseSuppressingInvocationHandler(targetthis));
	}

Invocation handler that suppresses close calls on JDBC Connections until the associated instance of the ExtendedConnectionDataSourceProxy determines the connection should actually be closed.
	private static class CloseSuppressingInvocationHandler implements InvocationHandler {
		private final Connection target;
			this. = dataSource;
			this. = target;
		}
		public Object invoke(Object proxyMethod methodObject[] argsthrows Throwable {
			// Invocation on ConnectionProxy interface coming in...
			if (method.getName().equals("equals")) {
				// Only consider equal when proxies are identical.
				return (proxy == args[0] ? . : .);
			}
			else if (method.getName().equals("hashCode")) {
				// Use hashCode of Connection proxy.
				return new Integer(System.identityHashCode(proxy));
			}
			else if (method.getName().equals("close")) {
				// Handle close method: don't pass the call on if we are
				// suppressing close calls.
					return null;
				}
				else {
					return null;
				}
			}
			else if (method.getName().equals("getTargetConnection")) {
				// Handle getTargetConnection method: return underlying
				// Connection.
				return this.;
			}
			// Invoke method on target Connection.
			try {
				return method.invoke(this.args);
			}
				throw ex.getTargetException();
			}
		}
	}

Performs only a 'shallow' non-recursive check of self's and delegate's class to retain Java 5 compatibility.
	public boolean isWrapperFor(Class<?> ifacethrows SQLException {
			return true;
		}
		return false;
	}

Returns either self or delegate (in this order) if one of them can be cast to supplied parameter class. Does *not* support recursive unwrapping of the delegate to retain Java 5 compatibility.
	public <T> T unwrap(Class<T> ifacethrows SQLException {
		if (iface.isAssignableFrom(SmartDataSource.class)) {
			@SuppressWarnings("unchecked")
casted = (T) this;
			return casted;
		}
		else if (iface.isAssignableFrom(.getClass())) {
			@SuppressWarnings("unchecked")
casted = (T) ;
			return casted;
		}
		throw new SQLException("Unsupported class " + iface.getSimpleName());
	}
	public void afterPropertiesSet() throws Exception {
	}
New to GrepCode? Check out our FAQ X