/* JFox, the OpenSource J2EE Application Server
 *
 * Copyright (C) 2002 huihoo.com
 * Distributable under GNU LGPL license
 * See the GNU Lesser General Public License for more details.
 */

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.huihoo.jfox.logging.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) {

  }
}