package dk.hansen;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.log4j.Logger;

public class JDBCTransaction implements JDBCTransactionIF {

  private static Logger logger = Logger.getLogger(JDBCTransaction.class
      .getName());

  private DataSource dataSource;

  private Connection connection;

  public void begin() throws DAOException {
    logger.debug("Begin transaction");
    createConnection();
    try {
      connection.setAutoCommit(false);
    } catch (SQLException e) {
      throw new DAOException("Could not set autocommit", e);
    }
  }

  public void end() throws DAOException {
    try {
      logger.debug("End transaction");
      connection.commit();
    } catch (SQLException e) {
      try {
        close();
      } catch (DAOException de) {
        logger.error("Close failed after commit failed", de);
      }
      throw new DAOException("Could not commit", e);
    }

    try {
      close();
    } catch (DAOException e) {
      throw new DAOException("Could not close", e);
    }
  }

  public void rollback() throws DAOException {
    try {
      logger.debug("Rollback transaction");
      connection.rollback();
    } catch (SQLException e) {
      try {
        close();
      } catch (DAOException de) {
        logger.error("Close failed after rollback failed", de);
      }
      throw new DAOException("Could not rollback", e);
    }

    try {
      close();
    } catch (DAOException e) {
      throw new DAOException("Could not close", e);
    }
  }

  private void close() throws DAOException {
    try {
      logger.debug("Close connection");
      connection.close();
      connection = null;
    } catch (SQLException e) {
      throw new DAOException("Could not close the connection", e);
    }
  }

  public void setDataSource(DataSource ds) {
    dataSource = ds;
  }

  public Connection getConnection() throws DAOException {
    logger.debug("Get a connection");
    try {
      if (connection == null || connection.isClosed())
        createConnection();
    } catch (SQLException e) {
      throw new DAOException("Could not check if connection was closed", e);
    }  
    logger.debug("Connection " + connection + " returned");
    return connection;
  }

  private void createConnection() throws DAOException {
    try {
      connection = dataSource.getConnection();
      logger.debug("New Connection created");
    } catch (SQLException e) {
      throw new DAOException("Could not create connection", e);
    }
  }
}