/*
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@objectweb.org
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY 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 along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */


package org.objectweb.jonas.jdbc_xa;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Vector;
import javax.transaction.xa.XAResource;
import javax.sql.ConnectionEvent;
import javax.sql.ConnectionEventListener;
import javax.sql.XAConnection;
import org.objectweb.jonas.common.Log;
import org.objectweb.util.monolog.api.Logger;
import org.objectweb.util.monolog.api.BasicLevel;

/**
 * This is the implementation of the XAConnection interface. This object
 * encapsulates 2 objects: the Connection and the XAResource.
 * Connection is used for std SQL primitive, XAResource is used for
 * XA primitive (transaction demarcation).
 *
 * @author Philippe Durieux
 * Contributor(s):
 */

class XAConnectionImpl implements XAConnection {

    static private Logger logger = null;

    XAResource xaRes = null;
    Connection implConn = null;
    Connection actConn = null;
    Vector eventListeners = new Vector();

    // -----------------------------------------------------------------
    // Constructors
    // -----------------------------------------------------------------

    public XAConnectionImpl(Connection conn, XADataSourceImpl ds) {

	this.actConn = conn;

	// An XAConnection holds 2 objects: 1 Connection + 1 XAResource
	this.implConn = new ConnectionImpl(this, conn);
	this.xaRes = new XAResourceImpl(this, conn, ds);
        logger = Log.getLogger(Log.JONAS_JDBCXA_PREFIX);
        logger.log(BasicLevel.DEBUG,"exiting");
    }

    // -----------------------------------------------------------------
    // XAConnection implementation
    // -----------------------------------------------------------------

    /**
     * Return an XA resource to the caller.
     *
     * @return The XAResource
     *
     * @exception SQLException - if a database-access error occurs
     */
    public XAResource getXAResource() throws SQLException {
	return xaRes;
    }

    // -----------------------------------------------------------------
    // PooledConnection implementation
    // -----------------------------------------------------------------

    /**
     * Create an object handle for a database connection.
     *
     * @exception SQLException - if a database-access error occurs
     */
    public Connection getConnection() throws SQLException {

	// Just return the already created object.
	return implConn;
    }

    /**
     * Close the database connection.
     *
     * @exception SQLException - if a database-access error occurs
     */
    public void close() throws SQLException {

	logger.log(BasicLevel.DEBUG, "entering");

	// Close the actual Connection here.
	actConn.close();
	actConn = null;

	// We can forget Connection and XAResource too.
	xaRes = null;
	implConn = null;
    }

    /**
     * Add an event listener.
     *
     * @param listener event listener
     */
    public void addConnectionEventListener(ConnectionEventListener listener) {

	logger.log(BasicLevel.DEBUG, "entering");
	eventListeners.addElement(listener);
    }

    /**
     * Remove an event listener.
     *
     * @param listener event listener
     */
    public void removeConnectionEventListener(ConnectionEventListener listener) {

	logger.log(BasicLevel.DEBUG, "entering");
	eventListeners.removeElement(listener);
    }

    // -----------------------------------------------------------------
    // Other methods
    // -----------------------------------------------------------------

    /*
     * Notify a Close event on Connection
     */
    public void notifyClose() {

	logger.log(BasicLevel.DEBUG, "entering");

	// Notify event to listeners
	for (int i = 0; i < eventListeners.size(); i++) {
	    ConnectionEventListener l = (ConnectionEventListener) eventListeners.elementAt(i);
	    l.connectionClosed(new ConnectionEvent(this));
	}
    }

    /*
     * Notify an Error event on Connection
     */
    public void notifyError(SQLException ex) {

	logger.log(BasicLevel.DEBUG, "entering");

	// Notify event to listeners
	for (int i = 0; i < eventListeners.size(); i++) {
	    ConnectionEventListener l = (ConnectionEventListener) eventListeners.elementAt(i);
	    l.connectionErrorOccurred(new ConnectionEvent(this, ex));
	}
    }


}
