/*
 * JBoss, Home of Professional Open Source
 * Copyright 2007, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags.
 * 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 General Public License, v. 2.0.
 * 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 General Public License for more details.
 * You should have received a copy of the GNU General Public License,
 * v. 2.0 along with this distribution; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 *
 * (C) 2007,
 * @author JBoss Inc.
 */
package org.jboss.txbridge.ba.datamgmt;

import org.apache.log4j.Logger;

import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;

/**
 * This component is responsible for ensuring that a proper Data Manager is provided
 * during execution of a service or a completion or compensation action. It associates
 * data managers with proper threads of execution.
 *
 * @author Maciej P. Machulak (mmachulak@redhat.com)
 * @version 0.1
 */
public class DataManagerProvider
{
    private static Logger log = Logger.getLogger(DataManagerProvider.class);

    private static volatile DataManagerProvider cmp = null;

    private static ConcurrentMap<Long, DataManager> cmList;

    private DataManagerProvider()
    {
        cmList = new ConcurrentHashMap<Long, DataManager>();
    }

    /**
     * Returns the instance of a data manager provider.
     *
     * @return the data manager provider.
     */
    public static DataManagerProvider getSingletonInstance()
    {
        log.info("getSingletonInstance()");
        if (cmp == null)
        {
            synchronized (DataManagerProvider.class)
            {
                if (cmp == null)
                {
                    log.info("Creating a new instance");
                    cmp = new DataManagerProvider();
                }
            }
        }
        return cmp;
    }

    /**
     * This method associates a data manager with a given thread of execution.
     *
     * @param thread is the thread for which the data manager should be associated.
     * @param cmp is the data manager, which should be associated.
     */
    public void associateManager(Long thread, DataManager cmp)
    {
        log.info("associateManager()");
        cmList.put(thread,cmp);
    }

    /**
     * This method returns the data manager object associated to a certain thread of execution.
     * If there is no data manager associated to a certain thread of execution then it means
     * the service is being executed outside the scope of the Business Activity and a dummy data
     * manager is simply returned.
     *
     * @param thread thread ID for which the data manager should be returned.
     * @return the DataManager object.
     */
    public DataManager getManager(Long thread)
    {
        log.info("getManager()");
        DataManager cm = cmList.get(thread);
        if (cm == null)
        {
            log.info("Returning a dummy data manager");
            cm = new DummyDataManager();
        }
        return cm;
    }

    /**
     * This method removes the association of a thread and a data manager.
     *
     * @param thread is the thread for which the associaction should be removed.
     */
    public void removeManager(Long thread)
    {
        log.info("removeManager()");
        cmList.remove(thread);
    }
}
