package sac.persistencia;

import java.sql.*;
import java.util.*;

/**
 * Esta classe é um "wrapper" de uma <code>Connection</code>. O método
 * <code>close</code> apenas informa ao pool que a conexão está novamente
 * disponível para uso; o método <code>isClosed</code> retorna o estado do
 * wrapper, ao invés da conexão verdadeira.
 * Essa classe é totalmente transparente ao usuário, que nem precisa saber que
 * ela existe (por isso não é pública). Para o usuário, ele está trabalhando
 * com uma <code>Connection</code> normal (devendo inclusive chamar o
 * <code>close</code> quando acabar de utilizá-la.
 */
class ConnectionWrapper implements Connection {
    private Connection realConn;
    private PoolConexoes pool;
    private boolean isClosed = false;
    
    ConnectionWrapper(Connection realConn, PoolConexoes pool) {
        this.realConn = realConn;
        this.pool = pool;
    }
   /*
    * Wrapped methods.
    */
    public void clearWarnings() throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        realConn.clearWarnings();
    }
    /**
     * Inform the ConnectionPool that the ConnectionWrapper
     * is closed.
     */
    public void close() throws SQLException {
        isClosed = true;
        pool.wrapperClosed(realConn);
    }
    public void commit() throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        realConn.commit();
    }
    public Statement createStatement() throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.createStatement();
    }
    public Statement createStatement(int resultSetType, 
            int resultSetConcurrency) throws java.sql.SQLException {
        if (this.isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.createStatement(resultSetType, resultSetConcurrency);
    }
    public boolean getAutoCommit() throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.getAutoCommit();
    }
    public String getCatalog() throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.getCatalog();
    }
    public DatabaseMetaData getMetaData() throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.getMetaData();
    }
    public int getTransactionIsolation() throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.getTransactionIsolation();
    }
    
    public Map getTypeMap() throws java.sql.SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.getTypeMap();
    }
    public SQLWarning getWarnings() throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.getWarnings();
    }
    
    public boolean isClosed() throws SQLException {
        return this.isClosed;
    }
    public boolean isReadOnly() throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.isReadOnly();
    }
    public String nativeSQL(String sql) throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.nativeSQL(sql);
    }
    public CallableStatement prepareCall(String sql) throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.prepareCall(sql);
    }
    
    public CallableStatement prepareCall(String sql, int resultSetType, 
            int resultSetConcurrency) throws java.sql.SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.prepareCall(sql, resultSetType, resultSetConcurrency);
    }
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.prepareStatement(sql);
    }
    
    public PreparedStatement prepareStatement(String sql, int resultSetType, 
            int resultSetConcurrency) throws java.sql.SQLException {
        if (this.isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        return realConn.prepareStatement(sql, resultSetType, 
                resultSetConcurrency);
    }
    public void rollback() throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        realConn.rollback();
    }
    public void setAutoCommit(boolean autoCommit) throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        realConn.setAutoCommit(autoCommit);
    }
    public void setCatalog(String catalog) throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        realConn.setCatalog(catalog);
    }
    public void setReadOnly(boolean readOnly) throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        realConn.setReadOnly(readOnly);
    }
    public void setTransactionIsolation(int level) throws SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        realConn.setTransactionIsolation(level);
    }
    public void setTypeMap(Map map) throws java.sql.SQLException {
        if (isClosed) {
            throw new SQLException("Pooled connection is closed");
        }
        realConn.setTypeMap(map);
        
    }
}
