/* 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.tm;

import javax.transaction.*;

/**
 * 
 * @author <a href="mailto:young_yy@hotmail.com">Young Yang</a>
 */

public class TxManager implements TransactionManager {

  private static ThreadLocal threadTx = new ThreadLocal() {
    protected Object initialValue() {
      return new TxWrapper();
    }

    public Object get() {
      Object obj = super.get();
      if(obj == null) {
        obj = initialValue();
        super.set(obj);
      }
      return obj;
    }
  };

  // singleton instance
  private static TxManager me = new TxManager();

  private volatile int numTrasactions = 0;
  private volatile int numSuspendedTransactions = 0;

  public static TxManager getInstance(){
    return me;
  }

  public void begin() throws NotSupportedException, SystemException {
    numTrasactions++;
    ((TxWrapper)threadTx.get()).begin();
  }

  public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException, SystemException {
    numTrasactions--;
    try {
      ((TxWrapper)threadTx.get()).commit();
    }
    finally {
      threadTx.set(null);
    }
  }

  public void rollback() throws IllegalStateException, SecurityException, SystemException {
    numTrasactions--;
    try {
      ((TxWrapper)threadTx.get()).rollback();
    }
    finally {
      threadTx.set(null);
    }
  }

  public int getStatus() throws SystemException {
    return ((TxWrapper)threadTx.get()).getStatus();
  }

  public Transaction getTransaction() throws SystemException {
    return (TxWrapper)threadTx.get();
  }

  public void setRollbackOnly() throws IllegalStateException, SystemException {
    ((TxWrapper)threadTx.get()).setRollbackOnly();
  }

  public void setTransactionTimeout(int seconds) throws SystemException {
    ((TxWrapper)threadTx.get()).setTimeout(seconds * 1000);
  }

  public Transaction suspend() throws SystemException {
    Transaction trans = ((TxWrapper)threadTx.get()).suspend();
    numSuspendedTransactions++;
    return trans;
  }

  public void resume(Transaction transaction) throws InvalidTransactionException, IllegalStateException, SystemException {
    if (transaction == null || !(transaction instanceof TransactionImpl)){
      throw new InvalidTransactionException(transaction + " is not a instance of " + TransactionImpl.class.getName());
    }
    ((TxWrapper)threadTx.get()).resume(transaction);
    numSuspendedTransactions--;
  }

  int getNumTransactions() {
    return numTrasactions;
  }

  int getNumSuspendedTransactions() {
    return numSuspendedTransactions;
  }

  public static void main(String[] args) {

  }
}