org.jboss.dashboard.database.ExternalDataSource.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.dashboard.database.ExternalDataSource.java

Source

/**
 * Copyright (C) 2012 JBoss Inc
 *
 * 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.jboss.dashboard.database;

import org.jboss.dashboard.database.hibernate.HibernateTxFragment;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Logger;

/**
 * A data source implementation that bounds its connections to the underlying transaction.
 * <p>When a connection is requested it gets a connection from the pool and attach such connection
 * to the current transaction. When the transaction completes the data source
 * connection is automatically completed as well.
 */
public class ExternalDataSource implements DataSource {

    /**
     * Get an external data source instance.
     * @param name The name to assign to the datasource.
     * @param dsEntry The object containing the connection configuration for this datasource.
     */
    public static ExternalDataSource lookup(String name, DataSourceEntry dsEntry) {
        ExternalDataSource ds = new ExternalDataSource();
        ds.setName(name);
        ds.setDataSourceEntry(dsEntry);
        ds.setDisableAutoCommit(true);
        return ds;
    }

    protected static transient Log log = LogFactory.getLog(ExternalDataSource.class.getName());
    protected String name;
    protected DataSourceEntry dataSourceEntry;
    protected transient Connection currentConnection;
    private PrintWriter printWriter = new PrintWriter(System.out);
    private int loginTimeOut = 0;
    private boolean disableAutoCommit;

    public ExternalDataSource() {
        this.name = null;
        this.dataSourceEntry = null;
        this.currentConnection = null;
        this.disableAutoCommit = true;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setDataSourceEntry(DataSourceEntry dataSourceEntry) {
        this.dataSourceEntry = dataSourceEntry;
    }

    public DataSourceEntry getDataSourceEntry() {
        return dataSourceEntry;
    }

    public int getLoginTimeout() throws SQLException {
        return loginTimeOut;
    }

    public void setLoginTimeout(int seconds) throws SQLException {
        this.loginTimeOut = seconds;
    }

    public PrintWriter getLogWriter() throws SQLException {
        return printWriter;
    }

    public void setLogWriter(PrintWriter out) throws SQLException {
        this.printWriter = out;
    }

    public boolean isDisableAutoCommit() {
        return disableAutoCommit;
    }

    public void setDisableAutoCommit(boolean disableAutoCommit) {
        this.disableAutoCommit = disableAutoCommit;
    }

    public Connection getConnection(String username, String password) throws SQLException {
        return getConnection();
    }

    public Connection getConnection() throws SQLException {
        if (currentConnection == null)
            initConnection();
        return currentConnection;
    }

    public Logger getParentLogger() {
        return null;
    }

    protected void initConnection() {
        try {
            new HibernateTxFragment() {
                protected void txFragment(Session session) throws Exception {
                    log.debug("Obtain data source connection: " + name);
                    // Bug Fix: under some circumstances, the dataSourceEntry attribute became out of sync with the Hibernate session.
                    dataSourceEntry = (DataSourceEntry) session.get(dataSourceEntry.getClass(),
                            dataSourceEntry.getDbid());
                    Connection conn = dataSourceEntry.getConnection();
                    setAutoCommit(conn, !disableAutoCommit);
                    currentConnection = conn;
                    registerForCallbackNotifications();
                }

                protected void beforeRollback() throws Exception {
                    // Rollback asap.
                    completeConnection(false);
                }

                protected void afterRollback() throws Exception {
                    // Rollback if before commit fails.
                    completeConnection(false);
                }

                protected void afterCommit() throws Exception {
                    // Commit as late as possible.
                    completeConnection(true);
                }
            }.execute();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    protected void completeConnection(boolean commit) throws SQLException {
        if (currentConnection != null && !currentConnection.isClosed()) {
            if (!getAutoCommit(currentConnection)) {
                log.debug(commit ? "Commit" : "Rollback" + " data source connection: " + name);
                if (commit)
                    currentConnection.commit();
                else
                    currentConnection.rollback();
            }
            currentConnection.close();
        }
        currentConnection = null;
    }

    protected boolean getAutoCommit(Connection conn) {
        try {
            return conn.getAutoCommit();
        } catch (SQLException e) {
            // Ignore problems when trying to get autocommit.
            // In some environments (Presidencia - Informix) when trying to get autocommit an exception is thrown.
            log.debug("Can not get autocommit for datasource: " + name, e);
            return true;
        }
    }

    protected void setAutoCommit(Connection conn, boolean autocommit) {
        try {
            if (getAutoCommit(conn) != autocommit) {
                conn.setAutoCommit(autocommit);
            }
        } catch (SQLException e) {
            // Ignore problems when trying to change autocommit.
            // In some environments (Presidencia - Informix) when trying to set autocommit=true an exception is thrown.
            log.debug("Can not set autocommit for datasource: " + name, e);
        }
    }

    public boolean isWrapperFor(Class<?> c) {
        return false;
    }

    public <T> T unwrap(Class<T> c) {
        return null;
    }

}