All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jpattern.orm.session.datasource.DataSourceConnection Maven / Gradle / Ivy

There is a newer version: 6.3.0
Show newest version
package com.jpattern.orm.session.datasource;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jpattern.orm.exception.OrmException;
import com.jpattern.orm.exception.OrmRollbackException;

public class DataSourceConnection implements IConnection {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	private ConnectionWrapper connectionWrapper;
	private List connectionCallers = new ArrayList();
	private boolean rollbackOnly = false;
	private boolean readOnly = false;
	private boolean valid = true;

	public DataSourceConnection(final DataSource dataSource, final boolean readOnly) {
		this.connectionWrapper = new ConnectionWrapper(dataSource);
		this.setReadOnly(readOnly);
	}

	@Override
	public void setTransactionIsolation(final int transactionIsolation) throws OrmException {
		try {
			this.connectionWrapper.setTransactionIsolation(transactionIsolation);
		} catch (SQLException e) {
			throw new OrmException(e);
		}
	}

	@Override
	public boolean isClosed() throws OrmException {
		try {
			return this.connectionWrapper.isClosed();
		} catch (SQLException e) {
			throw new OrmException(e);
		}
	}

	@Override
	public void rollback() throws OrmException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("rollback called");
		}
		if ((this.connectionCallers.size()==1) && !this.isReadOnly()) {
			try {
				if (this.logger.isDebugEnabled()) {
					this.logger.debug("performing rollback");
				}
				this.connectionWrapper.rollback();
			} catch (SQLException e) {
				throw new OrmException(e);
			}
		}
	}

	@Override
	public void commit() throws OrmException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("commit called");
		}
		if ((this.connectionCallers.size()==1) && !this.isReadOnly()) {
			if (this.rollbackOnly) {
				this.rollback();
				throw new OrmRollbackException("Transaction rolled back because it has been marked as rollback-only");
			}
			else {
				try {
					if (this.logger.isDebugEnabled()) {
						this.logger.debug("performing commit");
					}
					this.connectionWrapper.commit();
				} catch (SQLException e) {
					throw new OrmException(e);
				}
			}
		}
	}

	@Override
	public PreparedStatement prepareStatement(final String sql) throws OrmException {
		try {
			return this.connectionWrapper.prepareStatement(sql);
		} catch (SQLException e) {
			throw new OrmException(e);
		}
	}

	@Override
	public PreparedStatement prepareStatement(final String sql, final String[] generatedColumnNames) throws OrmException {
		try {
			return this.connectionWrapper.prepareStatement(sql, generatedColumnNames) ;
		} catch (SQLException e) {
			throw new OrmException(e);
		}
	}

	@Override
	public IStatement createStatement() throws OrmException {
		try {
			return new StatementWrapper(this.connectionWrapper.createStatement() , this);
		} catch (SQLException e) {
			throw new OrmException(e);
		}
	}

	@Override
	public void addCaller(final IConnectionCaller connectionCaller) throws OrmException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Caller " + connectionCaller + " registered");
		}
		this.connectionCallers.add(connectionCaller);
	}

	@Override
	public void close(final IConnectionCaller connectionCaller) throws OrmException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Caller " + connectionCaller + " called a close on transaction");
		}
		this.connectionCallers.remove(connectionCaller);
		if (this.connectionCallers.isEmpty()) {
			try {
				if (this.logger.isDebugEnabled()) {
					this.logger.debug("Closing SQL connection");
				}
				this.connectionWrapper.close();
				this.valid = false;
			} catch (SQLException e) {
				throw new OrmException(e);
			}
		}
	}

	@Override
	public void setRollbackOnly() throws OrmException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Transaction sets as a rollbackOnly");
		}
		this.rollbackOnly = true;
	}

	@Override
	public void setReadOnly(final boolean readOnly) throws OrmException {
		this.readOnly = readOnly;
	}

	@Override
	public boolean isValid() throws OrmException {
		return this.valid;
	}

	public boolean isReadOnly() {
		return this.readOnly;
	}

	class ConnectionWrapper {

		private java.sql.Connection connection;
		private final DataSource dataSource;
		private Savepoint savepoint;

		ConnectionWrapper(final DataSource dataSource) {
			this.dataSource = dataSource;
		}

		public void setTransactionIsolation(final int transactionIsolation) throws SQLException {
			this.validateConnection();
			this.connection.setTransactionIsolation(transactionIsolation);
		}

		public void rollback() throws SQLException {
			if (this.connection!=null) {
				if (this.savepoint==null) {
					this.connection.rollback();
				} else {
					this.connection.rollback(this.savepoint);
				}

			}
		}

		public void rollback(final Savepoint savepoint) throws SQLException {
			if (this.connection!=null) {
				this.connection.rollback(savepoint);
			}
		}

		public void commit() throws SQLException {
			if (this.connection!=null) {
				this.connection.commit();
			}
		}

		public Statement createStatement() throws SQLException {
			this.validateConnection();
			return this.connection.createStatement();
		}

		public PreparedStatement prepareStatement(final String sql) throws SQLException {
			this.validateConnection();
			return this.connection.prepareStatement(sql);
		}

		public PreparedStatement prepareStatement(final String sql, final String[] generatedColumnNames) throws SQLException {
			this.validateConnection();
			return this.connection.prepareStatement(sql, generatedColumnNames);
		}

		public void close() throws SQLException {
			if (this.connection!=null) {
				this.connection.close();
			}
		}

		public boolean isClosed() throws SQLException {
			if (this.connection!=null) {
				return this.connection.isClosed();
			}
			return true;
		}

		private void validateConnection() throws SQLException {
			if (!DataSourceConnection.this.isValid()) {
				throw new OrmException("Not possible to open a new java.sql.Connection");
			}
			if (this.isClosed()) {
				if (DataSourceConnection.this.logger.isDebugEnabled()) {
					DataSourceConnection.this.logger.debug("Sql connection is null or closed. Opening a new sql connection.");
				}
				Connection sqlConn = this.dataSource.getConnection();
				if (!DataSourceConnection.this.isReadOnly()) {
					this.savepoint = sqlConn.setSavepoint();
				}
				this.connection = sqlConn;
			}
		}

	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy