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

com.jpattern.orm.datasource.Connection Maven / Gradle / Ivy

package com.jpattern.orm.datasource;

import java.sql.SQLException;
import java.sql.Savepoint;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import com.jpattern.logger.ILogger;
import com.jpattern.orm.exception.OrmException;
import com.jpattern.orm.exception.OrmRollbackException;
import com.jpattern.orm.logger.OrmLogger;

public class Connection implements IConnection {

	private final ILogger logger;
	private final DataSource dataSource;
	private java.sql.Connection sqlConn = new FakeSqlConnection();
	private List connectionCallers = new ArrayList();
	private boolean rollbackOnly = false;
	private boolean readOnly = false;
	private Savepoint savepoint;
	private boolean valid = true; 

	public Connection(DataSource dataSource, boolean readOnly) {
		this.dataSource = dataSource;
		this.readOnly  = readOnly;
		logger = OrmLogger.getOrmLogger(getClass());
	}

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

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

	@Override
	public void rollback() throws OrmException {
		logger.debug("rollback", "rollback called");
		if (connectionCallers.size()==1 && !readOnly) {
			try {
				logger.info("rollback", "performing rollback");
				if (savepoint==null) {
					getSqlConnection(false).rollback();
				} else {
					getSqlConnection(false).rollback(savepoint);
				}
			} catch (SQLException e) {
				throw new OrmException(e);
			}
		}
	}

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

	@Override
	public PreparedStatementWrapper prepareStatement(String sql) throws OrmException {
		try {
			return new PreparedStatementWrapper( getSqlConnection(true).prepareStatement(sql) , this );
		} catch (SQLException e) {
			throw new OrmException(e);
		}
	}

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

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

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

	@Override
	public void close(IConnectionCaller connectionCaller) throws OrmException {
		logger.info("close", "Caller " + connectionCaller + " called a close on transaction");
		connectionCallers.remove(connectionCaller);
		if (connectionCallers.isEmpty()) {
			try {
				logger.info("close", "closing SQL connection");
				java.sql.Connection conn = getSqlConnection(false);
				if (conn!=null && !conn.isClosed()) {
					conn.close();
				}
				valid = false;
			} catch (SQLException e) {
				throw new OrmException(e);
			}
		}
	}

	@Override
	public void setRollbackOnly() throws OrmException {
		logger.info("setRollbackOnly", "Transaction sets as a rollbackOnly");
		this.rollbackOnly = true;
	}
	
	private java.sql.Connection getSqlConnection(boolean forceGoodConnection) {
		try {
			if (valid && forceGoodConnection && sqlConn.isClosed()) {
				logger.info("getSqlConnection", "Sql connection is null or closed. Opening a new sql connection.");
				sqlConn = dataSource.getConnection();
				if (readOnly) {
					savepoint = sqlConn.setSavepoint();
				}
			}
			return sqlConn;
		} catch (SQLException e) {
			throw new OrmException(e);
		}
		
	}

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

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy