/*
 *
 * 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
 *
 * Initial developer(s): ____________________________________.
 * Contributor(s):
 * 01/11/06 Christophe Ney cney@batisseurs.com for Lutris Technologies
 *          Added ResourceManagerListener mechanism to remove ThreadData
 *          dependency.
 * Dean Jennings : optimization
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */


package org.objectweb.jonas.thds;

import java.rmi.RemoteException;
import java.util.*;
import javax.naming.Context;
import org.objectweb.transaction.api.ResourceManagerEvent;
import org.objectweb.transaction.api.ResourceManagerEventListener;


/**
 * This object encapsulate a ThreadLocal data that holds the
 * list of connections open by the thread outside any transaction.
 */
public class ThreadData implements ResourceManagerEventListener {

    // ------------------------------------------------------------------
    // Private data
    // ------------------------------------------------------------------


    // list of connections open outside a transaction
    private ThreadLocal threadConnections = null;

    // -------------------------------------------------------------------
    // JOnAS Service Implementation
    // -------------------------------------------------------------------

    private static ThreadData unique = null;

    /**
     * Private constructor to force only 1 instance.
     */
    private ThreadData() {
	threadConnections = new ThreadLocal();
    }

    /**
     * Get the unique instance. Create it at first call.
     * Return an interface of the service.
     */
	public static ThreadData getInstance() {
	if (unique == null) {
	    unique = new ThreadData();
	}
	return unique;
    }

    /**
     * Start the Service
     * Configuration information is passed thru a Context object.
     */
    public void start(Context ctx) {
    }

    // -------------------------------------------------------------------
    // ResourceManagerEventListener Implementation
    // -------------------------------------------------------------------

    /**
     *  connection opened
     */
    public void connectionOpened(ResourceManagerEvent event) {

        List events = (List)threadConnections.get();
        if (events == null) {
            events = Collections.synchronizedList(new ArrayList());
            threadConnections.set(events);
        }
        events.add(event);
    }

    /**
     *  connection closed
     */
    public void connectionClosed(ResourceManagerEvent event) {
        // event must equal to the original event
        List events = (List)threadConnections.get();
        if (events != null) {
            events.remove(event);
        }
    }

    /**
     *  connection error
     */
    public void connectionErrorOccured(ResourceManagerEvent event){
        // event must equal to the original event
        List events = (List)threadConnections.get();
        if (events != null) {
            events.remove(event);
        }
    }

    // -------------------------------------------------------------------
    // Other methods, used by container and tm
    // -------------------------------------------------------------------

    /**
     * Set the connectionList and return old value.
     */
    public List setConnectionList(List list) {
	List oldlist = (List) threadConnections.get();
	threadConnections.set(list);
	return oldlist;
    }

    /**
     * Get the connectionList for this thread
     */
    public List getConnectionList() {
	List list = (List) threadConnections.get();
	return list;
    }

}
