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

com.arjuna.ats.internal.jdbc.recovery.JDBCXARecovery Maven / Gradle / Ivy

There is a newer version: 4.17.37.Final
Show newest version
/*
 * JBoss, Home of Professional Open Source
 * Copyright 2006, JBoss Inc., and others contributors as indicated
 * by the @authors tag. All rights reserved.
 * See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License, v. 2.1.
 * This program is distributed in the hope that it will be useful, but WITHOUT A
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 * You should have received a copy of the GNU Lesser General Public License,
 * v.2.1 along with this distribution; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 *
 * (C) 2005-2006,
 * @author JBoss Inc.
 */
/*
 * Copyright (C) 2004, 2005,
 *
 * Arjuna Technologies Limited,
 * Newcastle upon Tyne,
 * Tyne and Wear,
 * UK.
 *
 * $Id$
 */

package com.arjuna.ats.internal.jdbc.recovery;

import java.sql.SQLException;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.ConnectionEvent;
import javax.sql.ConnectionEventListener;
import javax.sql.XAConnection;
import javax.sql.XADataSource;
import javax.transaction.xa.XAResource;

import com.arjuna.ats.jdbc.logging.jdbcLogger;
import com.arjuna.ats.jta.recovery.XAResourceRecovery;
import com.arjuna.common.util.propertyservice.PropertiesFactory;

/**
 * This provides recovery for compliant JDBC drivers. It is not meant to be
 * implementation specific.
 *
 * Users are responsible for deploying an appropriate XADataSource into JNDI and
 * then providing the relevant JNDI lookup information in a property file to an
 * instance of this class. Username and password values may also be provided in
 * the same property file.
 */

public class JDBCXARecovery implements XAResourceRecovery
{
    public static final String DATABASE_JNDI_NAME = "DatabaseJNDIName";
    public static final String USER_NAME          = "UserName";
    public static final String PASSWORD           = "Password";

    /*
     * Some XAResourceRecovery implementations will do their startup work here,
     * and then do little or nothing in setDetails. Since this one needs to know
     * dynamic class name, the constructor does nothing.
     */

    public JDBCXARecovery()
        throws SQLException
    {
        if (jdbcLogger.logger.isDebugEnabled())
            jdbcLogger.logger.debug("JDBCXARecovery()");

        _props                   = null;
        _hasMoreResources        = false;
        _connectionEventListener = new LocalConnectionEventListener();
    }

    /**
     * The recovery module will have chopped off this class name already. The
     * parameter should specify a property file from which the jndi name, user name,
     * password can be read.
     */

    public boolean initialise(String parameter)
        throws SQLException
    {
        if (jdbcLogger.logger.isDebugEnabled())
            jdbcLogger.logger.debug("JDBCXARecovery.initialise(" + parameter + ")");

        if (parameter == null)
            return false;

        try
        {
            _props = PropertiesFactory.getPropertiesFromFile(parameter, JDBCXARecovery.class.getClassLoader());

            _dbName   = _props.getProperty(DATABASE_JNDI_NAME);
            _user     = _props.getProperty(USER_NAME);
            _password = _props.getProperty(PASSWORD);
        }
        catch (Exception e)
        {
            jdbcLogger.i18NLogger.warn_recovery_xa_initexp(e);

            return false;
        }

        return true;
    }

    public synchronized XAResource getXAResource()
        throws SQLException
    {
        createConnection();

        return _connection.getXAResource();
    }

    public boolean hasMoreResources()
    {
        if (_dataSource == null)
            try
            {
                createDataSource();
            }
            catch (SQLException sqlException)
            {
                return false;
            }

        if (_dataSource != null)
        {
            _hasMoreResources = ! _hasMoreResources;

            return _hasMoreResources;
        }
        else
            return false;
    }

    /**
     * Lookup the XADataSource in JNDI. We got the relevant information from the
     * property file provided at input to this instance.
     */

    private final void createDataSource()
        throws SQLException
    {
        try
        {
            if (_dataSource == null)
            {
                Context context = new InitialContext();
                _dataSource = (XADataSource) context.lookup(_dbName);

                if (_dataSource == null)
                    throw new SQLException(jdbcLogger.i18NLogger.get_xa_recjndierror());
            }
        }
        catch (SQLException ex)
        {
            ex.printStackTrace();

            throw ex;
        }
        catch (Exception e)
        {
            e.printStackTrace();

            SQLException sqlException = new SQLException(e.toString());
            sqlException.initCause(e);
            throw sqlException;
        }
    }

    /**
     * Create the XAConnection from the XADataSource.
     */

    private final void createConnection()
        throws SQLException
    {
        try
        {
            if (_dataSource == null)
                createDataSource();

            if (_connection == null)
            {
                if ((_user == null) && (_password == null))
                    _connection = _dataSource.getXAConnection();
                else
                    _connection = _dataSource.getXAConnection(_user, _password);

                _connection.addConnectionEventListener(_connectionEventListener);
            }
        }
        catch (SQLException ex)
        {
            ex.printStackTrace();

            throw ex;
        }
        catch (Exception e)
        {
            e.printStackTrace();

            SQLException sqlException = new SQLException(e.toString());
            sqlException.initCause(e);
            throw sqlException;
        }
    }

    private class LocalConnectionEventListener implements ConnectionEventListener
    {
        public void connectionErrorOccurred(ConnectionEvent connectionEvent)
        {
            _connection.removeConnectionEventListener(_connectionEventListener);
            _connection = null;
        }

        public void connectionClosed(ConnectionEvent connectionEvent)
        {
            _connection.removeConnectionEventListener(_connectionEventListener);
            _connection = null;
        }
    }

    private XAConnection                 _connection;
    private XADataSource                 _dataSource;
    private LocalConnectionEventListener _connectionEventListener;
    private Properties                   _props;
    private String                       _dbName;
    private String                       _user;
    private String                       _password;
    private boolean                      _hasMoreResources;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy