/* JFox, the OpenSource J2EE Application Server
 *
 * Distributable under GNU LGPL license by gun.org
 * more details please visit http://www.huihoo.org/jfox
 */

package org.jfox.jdbc.xa;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.sql.XAConnection;
import javax.transaction.Transaction;

import org.jfox.framework.logger.Logger;


/**
 * 维护 Transaction <=> XAConnection 的对应关系
 * 在同一个事务中，每次 XADataSource.getXAConnection() 得到的应该是同一个 XAConnection
 *
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class XAConnectionManager {

    // transaction <=> Map(url+user+pass=>xaconn)
    private static Map tran2xaconns = Collections.synchronizedMap(new HashMap());
    private static Logger logger = Logger.getLogger(XAConnectionManager.class.getName());

/*
  public static void associate(Transaction tran, XAConnection xaconn) {
    logger.debug("associate: " + tran + " => " + xaconn);
    tran2xaconns.put(tran,xaconn);
  }

  public static boolean isAssociated(Transaction tran){
    boolean boo = tran2xaconns.containsKey(tran);
    logger.debug("isAssocated " + boo + ", transaction = " + tran);
    return boo;
  }

  public static PoolableXAConnection getXAConnection(Transaction tran){
    logger.debug("getXAConnection " + tran);
    return (PoolableXAConnection)tran2xaconns.get(tran);
  }
*/
    public static void disassociate(Transaction tran) {
        logger.debug("disassociate " + tran);
        tran2xaconns.remove(tran);
    }

    public static void disassociate(Transaction tran, String dbUrl, String user, String password) {
        logger.debug("disassociate transaction=>" + tran + ", " + key(dbUrl, user, password));
        if(tran2xaconns.containsKey(tran)) {
            Map trans = (Map) tran2xaconns.get(tran);
            trans.remove(key(dbUrl, user, password));
            if(trans.isEmpty()) {
                tran2xaconns.remove(tran);
            }
        }
        tran2xaconns.remove(tran);
    }


    public static void associate(Transaction tran, XAConnection xaconn, String dbUrl, String user, String pass) {
        logger.debug("associate: " + tran + " => " + xaconn);
        if(tran2xaconns.containsKey(tran)) {
            Map trans = (Map) tran2xaconns.get(tran);
            trans.put(key(dbUrl, user, pass), xaconn);
        }
        else {
            Map trans = new HashMap();
            trans.put(key(dbUrl, user, pass), xaconn);
            tran2xaconns.put(tran, trans);
        }
    }

    public static boolean isAssociated(Transaction tran, String dbUrl, String user, String pass) {
        boolean boo = tran2xaconns.containsKey(tran);
        if(boo == true) {
            boo = ((Map) tran2xaconns.get(tran)).containsKey(key(dbUrl, user, pass));
        }
        logger.debug("isAssocated " + boo + ", transaction = " + tran + "," + key(dbUrl, user, pass));
        return boo;
    }

    public static PoolableXAConnection getXAConnection(Transaction tran, String dbUrl, String user, String pass) {
        logger.debug("getXAConnection " + tran + ", " + key(dbUrl, user, pass));
        if(!tran2xaconns.containsKey(tran)) {
            return null;
        }
        else {
            return (PoolableXAConnection) ((Map) tran2xaconns.get(tran)).get(key(dbUrl, user, pass));
        }
    }

    private static String key(String dbUrl, String user, String pass) {
        StringBuffer sb = new StringBuffer();
        sb.append(dbUrl).append(";user=").append(user).append(";password=").append(pass);
        return sb.toString();
    }

    public static void main(String[] args) {

    }
}

