/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.geode.internal.jta;

/**
 * <p>
 * TransactionManager: A JTA compatible Transaction Manager.
 * </p>
 *
 * @since GemFire 4.1.1
 *
 * @deprecated as of Geode 1.2.0 user should use a third party JTA transaction manager instead.
 */

import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.InvalidTransactionException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;

import org.apache.logging.log4j.Logger;

import org.apache.geode.CancelException;
import org.apache.geode.LogWriter;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.logging.internal.executors.LoggingThread;
import org.apache.geode.logging.internal.log4j.api.LogService;

@Deprecated
public class TransactionManagerImpl implements TransactionManager, Serializable {
  private static final long serialVersionUID = 5033392316185449821L;

  private static final Logger logger = LogService.getLogger();
  /**
   * A mapping of Thread - Transaction Objects
   */
  private Map transactionMap = new ConcurrentHashMap();
  /**
   * A mapping of Transaction - Global Transaction
   */
  private Map globalTransactionMap = Collections.synchronizedMap(new HashMap());
  /**
   * Ordered set of active global transactions - Used for timeOut
   */
  protected SortedSet gtxSet =
      Collections.synchronizedSortedSet(new TreeSet(new GlobalTransactionComparator()));
  /**
   * Transaction TimeOut Class
   */
  private transient TransactionTimeOutThread cleaner;
  /**
   * Singleton transactionManager
   */
  @MakeNotStatic
  private static TransactionManagerImpl transactionManager = null;
  /**
   * Transaction TimeOut thread
   */
  private transient Thread cleanUpThread = null;
  /**
   * Default Transaction Time Out
   */
  static final int DEFAULT_TRANSACTION_TIMEOUT =
      Integer.getInteger("jta.defaultTimeout", 600).intValue();
  /**
   * Asif: The integers identifying the cause of Rollback
   */
  private static final int MARKED_ROLLBACK = 1;
  private static final int EXCEPTION_IN_NOTIFY_BEFORE_COMPLETION = 2;
  private static final int COMMIT_FAILED_SO_ROLLEDBAK = 3;
  private static final int COMMIT_FAILED_ROLLBAK_ALSO_FAILED = 4;
  private static final int ROLLBAK_FAILED = 5;
  // TODO:Asif .Not yet used this exception code
  // private static final int EXCEPTION_IN_NOTIFY_AFTER_COMPLETION = 6;
  /*
   * to enable VERBOSE = true pass System parameter jta.VERBOSE = true while running the test.
   */
  private static final boolean VERBOSE = Boolean.getBoolean("jta.VERBOSE");
  /*
   * checks if the TransactionManager is active
   */
  private boolean isActive = true;

  private final transient AtomicBoolean loggedJTATransactionManagerDeprecatedWarning =
      new AtomicBoolean(false);

  /**
   * Constructs a new TransactionManagerImpl
   */
  private TransactionManagerImpl() {
    cleaner = new TransactionTimeOutThread();
    cleanUpThread = new LoggingThread("GlobalTXTimeoutMonitor", cleaner);
    cleanUpThread.start();
  }

  /**
   * Returns the singleton TransactionManagerImpl Object
   */
  public static TransactionManagerImpl getTransactionManager() {
    if (transactionManager == null) {
      createTransactionManager();
    }
    return transactionManager;
  }

  /**
   * Creates an instance of TransactionManagerImpl if none exists
   */
  private static synchronized void createTransactionManager() {
    if (transactionManager == null)
      transactionManager = new TransactionManagerImpl();
  }

  /**
   * Create a new transaction and associate it with the current thread if none exists with the
   * current thread else throw an exception since nested transactions are not supported
   *
   * Create a global transaction and associate the transaction created with the global transaction
   *
   * @throws NotSupportedException - Thrown if the thread is already associated with a transaction
   *         and the Transaction Manager implementation does not support nested transactions.
   * @throws SystemException - Thrown if the transaction manager encounters an unexpected error
   *         condition.
   *
   * @see javax.transaction.TransactionManager#begin()
   */
  @Override
  public void begin() throws NotSupportedException, SystemException {
    if (loggedJTATransactionManagerDeprecatedWarning.compareAndSet(false, true)) {
      logger.warn(
          "Geode JTA transaction manager is deprecated since 1.2.0, please use a third party JTA transaction manager instead");
    }
    if (!isActive) {
      throw new SystemException(
          "TransactionManager invalid");
    }
    LogWriter log = TransactionUtils.getLogWriter();
    if (log.fineEnabled()) {
      log.fine("TransactionManager.begin() invoked");
    }
    Thread thread = Thread.currentThread();
    if (transactionMap.get(thread) != null) {
      String exception =
          "Nested transaction is not supported";
      if (VERBOSE)
        log.fine(exception);
      throw new NotSupportedException(exception);
    }
    try {
      TransactionImpl transaction = new TransactionImpl();
      transactionMap.put(thread, transaction);
      GlobalTransaction globalTransaction = new GlobalTransaction();
      globalTransactionMap.put(transaction, globalTransaction);
      globalTransaction.addTransaction(transaction);
      globalTransaction.setStatus(Status.STATUS_ACTIVE);
    } catch (Exception e) {
      String exception = String.format("SystemException due to %s",
          new Object[] {e});
      if (log.severeEnabled())
        log.severe(String.format("SystemException due to %s",
            new Object[] {e}));
      throw new SystemException(exception);
    }
  }

  /**
   * Complete the transaction associated with the current thread by calling the
   * GlobalTransaction.commit(). When this method completes, the thread is no longer associated with
   * a transaction.
   *
   * @throws RollbackException - Thrown to indicate that the transaction has been rolled back rather
   *         than committed.
   * @throws HeuristicMixedException - Thrown to indicate that a heuristic decision was made and
   *         that some relevant updates have been committed while others have been rolled back.
   * @throws HeuristicRollbackException - Thrown to indicate that a heuristic decision was made and
   *         that all relevant updates have been rolled back.
   * @throws java.lang.SecurityException - Thrown to indicate that the thread is not allowed to
   *         commit the transaction.
   * @throws java.lang.IllegalStateException - Thrown if the current thread is not associated with a
   *         transaction.
   * @throws SystemException - Thrown if the transaction manager encounters an unexpected error
   *         condition.
   *
   * @see javax.transaction.TransactionManager#commit()
   */
  @Override
  public void commit() throws HeuristicRollbackException, RollbackException,
      HeuristicMixedException, SystemException {
    if (!isActive) {
      throw new SystemException(
          "TransactionManager invalid");
    }
    int cozOfException = -1;
    Transaction transactionImpl = getTransaction();
    if (transactionImpl == null) {
      String exception =
          "Transaction is null, cannot commit a null transaction";
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE)
        writer.fine(exception);
      throw new IllegalStateException(exception);
    }
    GlobalTransaction gtx = getGlobalTransaction(transactionImpl);
    if (gtx == null) {
      String exception =
          "Global Transaction is null, cannot commit a null global transaction";
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE)
        writer.fine(exception);
      throw new SystemException(exception);
    }
    boolean isCommit = false;
    // ensure only one thread can commit. Use a synchronized block
    // Asif
    int status = -1;
    if (((status = gtx.getStatus()) == Status.STATUS_ACTIVE)
        || status == Status.STATUS_MARKED_ROLLBACK) {
      synchronized (gtx) {
        if ((status = gtx.getStatus()) == Status.STATUS_ACTIVE) {
          gtx.setStatus(Status.STATUS_COMMITTING);
          isCommit = true;
        } else if (status == Status.STATUS_MARKED_ROLLBACK) {
          gtx.setStatus(Status.STATUS_ROLLING_BACK);
          cozOfException = MARKED_ROLLBACK;
        } else {
          String exception =
              String.format("transaction not active, cannot be committed. Transaction Status= %s",
                  Integer.valueOf(status));
          LogWriter writer = TransactionUtils.getLogWriter();
          if (VERBOSE)
            writer.fine(exception);
          throw new IllegalStateException(exception);
        }
      }
    } else {
      String exception =
          "transaction is not active and cannot be committed";
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE)
        writer.fine(exception);
      throw new IllegalStateException(exception);
    }
    // Only one thread can call commit (the first thread to do reach the block
    // above).
    // Before commiting the notifications to be done before the done are called
    // the global transaction is called and then the after completion
    // notifications
    // are taken care of. The transactions associated to the global
    // transactions are
    // removed from the map and also the tread to transaction.
    //
    // Asif : Store the thrown Exception in case of commit .
    // Reuse it for thrwing later.
    // Asif TODO:Verify if it is a good practise
    boolean isClean = false;
    Exception e = null;
    try {
      ((TransactionImpl) transactionImpl).notifyBeforeCompletion();
      isClean = true;
    } catch (Exception ge) {
      // Asif : Just mark the Tranxn to setRollbackOnly to ensure Rollback
      setRollbackOnly();
      cozOfException = EXCEPTION_IN_NOTIFY_BEFORE_COMPLETION;
      e = ge;
    }
    // TODO:Asif In case the status of transaction is marked as
    // ROLLING_BACK , then we don't have to take a synch block
    // As once the status is marked for ROLLING_BACK , setRollnbackonly
    // will be harmless
    if (isCommit) {
      synchronized (gtx) {
        if ((status = gtx.getStatus()) == Status.STATUS_COMMITTING) {
          // Asif: Catch any exception encountered during commit
          // and appropriately mark the exception code
          try {
            gtx.commit();
          } catch (RollbackException rbe) {
            e = rbe;
            cozOfException = COMMIT_FAILED_SO_ROLLEDBAK;
          } catch (SystemException se) {
            e = se;
            cozOfException = COMMIT_FAILED_ROLLBAK_ALSO_FAILED;
          }
        } else if (status == Status.STATUS_ROLLING_BACK) {
          try {
            gtx.rollback();
            if (isClean)
              cozOfException = MARKED_ROLLBACK;
          } catch (SystemException se) {
            e = se;
            cozOfException = ROLLBAK_FAILED;
          }
        }
      }
    } else {
      try {
        gtx.rollback();
      } catch (SystemException se) {
        e = se;
        cozOfException = ROLLBAK_FAILED;
      }
    }
    try {
      ((TransactionImpl) transactionImpl).notifyAfterCompletion(status = gtx.getStatus());
    } catch (Exception ge) {
      LogWriter writer = TransactionUtils.getLogWriter();
      if (writer.infoEnabled())
        writer.info(
            String.format("Exception in notify after completion due to %s",
                ge.getMessage()),
            ge);
    }
    Thread thread = Thread.currentThread();
    transactionMap.remove(thread);
    this.gtxSet.remove(gtx);
    if (status != Status.STATUS_COMMITTED) {
      switch (cozOfException) {
        case EXCEPTION_IN_NOTIFY_BEFORE_COMPLETION: {
          String exception =
              "Transaction rolled back because of Exception in notifyBeforeCompletion processing";
          LogWriter writer = TransactionUtils.getLogWriter();
          if (VERBOSE)
            writer.fine(exception, e);
          RollbackException re = new RollbackException(exception);
          re.initCause(e);
          throw re;
        }
        case MARKED_ROLLBACK: {
          String exception =
              "Transaction rolled back because a user marked it for Rollback";
          LogWriter writer = TransactionUtils.getLogWriter();
          if (VERBOSE)
            writer.fine(exception, e);
          throw new RollbackException(exception);
        }
        case COMMIT_FAILED_SO_ROLLEDBAK: {
          LogWriter writer = TransactionUtils.getLogWriter();
          if (VERBOSE)
            writer.fine(e);
          throw (RollbackException) e;
        }
        case COMMIT_FAILED_ROLLBAK_ALSO_FAILED:
        case ROLLBAK_FAILED: {
          LogWriter writer = TransactionUtils.getLogWriter();
          if (VERBOSE)
            writer.fine(e);
          throw (SystemException) e;
        }
      }
    }
    gtx.setStatus(Status.STATUS_NO_TRANSACTION);
  }

  /**
   * Rolls back the transaction associated with the current thread by calling the
   * GlobalTransaction.rollback(). When this method completes, the thread is no longer associated
   * with a transaction.
   *
   * @throws java.lang.SecurityException - Thrown to indicate that the thread is not allowed to
   *         commit the transaction.
   * @throws java.lang.IllegalStateException - Thrown if the current thread is not associated with a
   *         transaction.
   * @throws SystemException - Thrown if the transaction manager encounters an unexpected error
   *         condition.
   *
   * @see javax.transaction.TransactionManager#commit()
   */
  @Override
  public void rollback() throws IllegalStateException, SecurityException, SystemException {
    if (!isActive) {
      throw new SystemException(
          "TransactionManager invalid");
    }
    // boolean isRollingBack = false;
    LogWriter writer = TransactionUtils.getLogWriter();
    Transaction transactionImpl = getTransaction();
    if (transactionImpl == null) {
      String exception =
          "no transaction exists";
      if (VERBOSE)
        writer.fine(exception);
      throw new IllegalStateException(exception);
    }
    GlobalTransaction gtx = getGlobalTransaction(transactionImpl);
    if (gtx == null) {
      String exception =
          "no global transaction exists";
      if (VERBOSE)
        writer.fine(exception);
      throw new SystemException(exception);
    }
    int status = gtx.getStatus();
    if (!(status == Status.STATUS_ACTIVE || status == Status.STATUS_MARKED_ROLLBACK)) {
      String exception =
          String.format("Transaction status does not allow Rollback .Transactional status, %s",
              Integer.valueOf(status));
      if (VERBOSE)
        writer.fine(exception);
      throw new IllegalStateException(exception);
    }
    // ensure only one thread proceeds from here
    status = -1;
    synchronized (gtx) {
      if ((status = gtx.getStatus()) == Status.STATUS_ACTIVE
          || status == Status.STATUS_MARKED_ROLLBACK)
        gtx.setStatus(Status.STATUS_ROLLING_BACK);
      else if (gtx.getStatus() == Status.STATUS_ROLLING_BACK) {
        String exception =
            String.format("Transaction already in a Rolling Back state.Transactional status, %s",
                Integer.valueOf(status));
        if (VERBOSE)
          writer.fine(exception);
        throw new IllegalStateException(exception);
      } else {
        String exception =
            "Transaction status does not allow Rollback";
        if (VERBOSE)
          writer.fine(exception);
        throw new IllegalStateException(exception);
      }
    }
    // Only one thread can call rollback (the first thread to do reach the
    // block above).
    // Before rollback the notifications to be done before the done are called
    // the global transaction is called and then the after completion
    // notifications
    // are taken care of. The transactions associated to the global
    // transactions are
    // removed from the map and also the tread to transaction.
    //
    // TODO remove all threads-transactions (from the map)
    // for transactions participating in the global transaction
    //
    SystemException se = null;
    try {
      gtx.rollback();
    } catch (SystemException se1) {
      se = se1;
    }
    try {
      ((TransactionImpl) transactionImpl).notifyAfterCompletion(gtx.getStatus());
    } catch (Exception e1) {
      if (writer.infoEnabled())
        writer.info(
            String.format("Exception in notify after completion due to %s",
                e1.getMessage()),
            e1);
    }
    Thread thread = Thread.currentThread();
    transactionMap.remove(thread);
    this.gtxSet.remove(gtx);
    if (se != null) {
      if (VERBOSE)
        writer.fine(se);
      throw se;
    }
    gtx.setStatus(Status.STATUS_NO_TRANSACTION);
  }

  /**
   * Set the Global Transaction status (Associated with the current thread) to be RollBackOnly
   *
   * Becauce we are using one phase commit, we are not considering Prepared and preparing states.
   *
   * @see javax.transaction.TransactionManager#setRollbackOnly()
   */
  @Override
  public void setRollbackOnly() throws IllegalStateException, SystemException {
    if (!isActive) {
      throw new SystemException(
          "TransactionManager invalid");
    }
    GlobalTransaction gtx = getGlobalTransaction();
    if (gtx == null) {
      String exception =
          "no global transaction exists";
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE)
        writer.fine(exception);
      throw new SystemException(exception);
    }
    synchronized (gtx) {
      int status = gtx.getStatus();
      if (status == Status.STATUS_ACTIVE)
        gtx.setRollbackOnly();
      else if (status == Status.STATUS_COMMITTING)
        gtx.setStatus(Status.STATUS_ROLLING_BACK);
      else if (status == Status.STATUS_ROLLING_BACK)
        ; // Dont do anything
      else {
        String exception =
            String.format("Transaction cannot be marked for rollback. Transcation status, %s",
                Integer.valueOf(status));
        LogWriter writer = TransactionUtils.getLogWriter();
        if (VERBOSE)
          writer.fine(exception);
        throw new IllegalStateException(exception);
      }
    }
    // Asif : Log after exiting synch block
    LogWriter writer = TransactionUtils.getLogWriter();
    if (VERBOSE)
      writer.fine("Transaction Set to Rollback only");
  }

  /**
   * Get the status of the global transaction associated with this thread
   *
   * @see javax.transaction.TransactionManager#getStatus()
   */
  @Override
  public int getStatus() throws SystemException {
    if (!isActive) {
      throw new SystemException(
          "TransactionManager invalid");
    }
    GlobalTransaction gtx = getGlobalTransaction();
    if (gtx == null) {
      return Status.STATUS_NO_TRANSACTION;
    }
    return gtx.getStatus();
  }

  /**
   * not supported
   *
   * @see javax.transaction.TransactionManager#setTransactionTimeout(int)
   */
  @Override
  public void setTransactionTimeout(int seconds) throws SystemException {
    if (!isActive) {
      throw new SystemException(
          "TransactionManager invalid");
    }
    GlobalTransaction gtx = getGlobalTransaction();
    if (gtx == null) {
      String exception =
          "no global transaction exists";
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE)
        writer.fine(exception);
      throw new SystemException(exception);
    }
    long newExpiry = gtx.setTransactionTimeoutForXARes(seconds);
    if (newExpiry > 0) {
      // long expirationTime = System.currentTimeMillis() + (seconds * 1000);
      gtxSet.remove(gtx);
      // Asif :Lets blindly remove the current gtx from the TreeMap &
      // Add only if status is neither Rolledback, Unknown , committed or no
      // transaction or GTX not
      // expired, which gurantees that the client thread will be returning &
      // cleaning up .so we
      // don't add it
      int status = gtx.getStatus();
      if (status != Status.STATUS_NO_TRANSACTION && status != Status.STATUS_COMMITTED
          && status != Status.STATUS_ROLLEDBACK && !gtx.isExpired()) {
        // Asif : Take a lock on GTX while setting the new Transaction timeout
        // value,
        // so that cleaner thread sees the new value immediately else due to
        // volatility issue
        // we may have inconsistent values of time out
        boolean toAdd = false;
        synchronized (gtx) {
          if (!gtx.isExpired()) {
            gtx.setTimeoutValue(newExpiry);
            toAdd = true;
          }
        }
        // Asif : It is possible that in the window between we set the new
        // timeout value in current GTX & add it to the gtxSet , the currentGtx
        // is expired by the cleaner thread as there is no safeguard for it.
        // We allow it to happen that is add the expired GTx to the TreeSet.
        // Since a notify will be issued , the cleaner thread wil take care
        // of it.
        if (toAdd) {
          synchronized (gtxSet) {
            gtxSet.add(gtx);
            if (gtxSet.first() == gtx) {
              gtxSet.notify();
            }
          }
        }
      } else {
        String exception =
            "Transaction has either expired or rolledback or committed";
        LogWriter writer = TransactionUtils.getLogWriter();
        if (VERBOSE)
          writer.fine(exception);
        throw new SystemException(exception);
      }
    }
  }

  /**
   * @see javax.transaction.TransactionManager#suspend()
   */
  @Override
  public Transaction suspend() throws SystemException {
    if (!isActive) {
      throw new SystemException(
          "TransactionManager invalid");
    }
    Transaction txn = getTransaction();

    if (null != txn) {
      GlobalTransaction gtx = getGlobalTransaction(txn);
      gtx.suspend();
      transactionMap.remove(Thread.currentThread());
      LogWriter writer = TransactionUtils.getLogWriter();
      if (writer.infoEnabled())
        writer.info(
            "Transaction suspended");
    }

    return txn;
  }

  /**
   * @see javax.transaction.TransactionManager#resume(javax.transaction.Transaction)
   */
  @Override
  public void resume(Transaction txn)
      throws InvalidTransactionException, IllegalStateException, SystemException {
    if (!isActive) {
      throw new SystemException(
          "TransactionManager invalid");
    }
    if (txn == null) {
      String exception =
          "cannot resume a null transaction";
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE)
        writer.fine(exception);
      throw new InvalidTransactionException(exception);
    }
    GlobalTransaction gtx = getGlobalTransaction(txn);
    if (gtx == null) {
      String exception =
          "cannot resume a null transaction";
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE)
        writer.fine(exception);
      throw new InvalidTransactionException(exception);
    }
    gtx.resume();
    try {
      Thread thread = Thread.currentThread();
      transactionMap.put(thread, txn);
      LogWriter writer = TransactionUtils.getLogWriter();
      if (writer.infoEnabled())
        writer.info(
            "Transaction resumed");
    } catch (Exception e) {
      String exception =
          String.format("Error in listing thread to transaction map due to %s",
              e);
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE)
        writer.fine(exception);
      throw new SystemException(exception);
    }
  }

  /**
   * Get the transaction associated with the calling thread
   *
   * @see javax.transaction.TransactionManager#getTransaction()
   */
  @Override
  public Transaction getTransaction() throws SystemException {
    if (!isActive) {
      throw new SystemException(
          "TransactionManager invalid");
    }
    Thread thread = Thread.currentThread();
    Transaction txn = (Transaction) transactionMap.get(thread);
    return txn;
  }

  /**
   * Get the Global Transaction associated with the calling thread
   */
  GlobalTransaction getGlobalTransaction() throws SystemException {
    Transaction txn = getTransaction();
    if (txn == null) {
      return null;
    }
    GlobalTransaction gtx = (GlobalTransaction) globalTransactionMap.get(txn);
    return gtx;
  }

  /**
   * Get the Global Transaction associated with the calling thread
   */
  GlobalTransaction getGlobalTransaction(Transaction txn) throws SystemException {
    if (txn == null) {
      String exception =
          "no transaction exists";
      LogWriter writer = TransactionUtils.getLogWriter();
      if (VERBOSE)
        writer.fine(exception);
      throw new SystemException(exception);
    }
    GlobalTransaction gtx = (GlobalTransaction) globalTransactionMap.get(txn);
    return gtx;
  }

  // Asif : This method is used only for testing purposes
  Map getGlobalTransactionMap() {
    return globalTransactionMap;
  }

  // Asif : This method is used only for testing purposes
  Map getTransactionMap() {
    return transactionMap;
  }

  // Asif : Remove the mapping of tranxn to Global Tranxn.
  // Previously thsi task was being done in GlobalTranxn
  void cleanGlobalTransactionMap(List tranxns) {
    synchronized (tranxns) {
      Iterator iterator = tranxns.iterator();
      while (iterator.hasNext()) {
        globalTransactionMap.remove(iterator.next());
      }
    }
  }

  void removeTranxnMappingsAndRollbackExpiredTransaction(List tranxns) {
    Object[] threads = transactionMap.keySet().toArray();
    int len = threads.length;
    Object tx = null;
    boolean removed = false;
    Object temp = null;
    for (int i = 0; i < len; ++i) {
      tx = transactionMap.get((temp = threads[i]));
      removed = tranxns.remove(tx);
      if (removed) {
        transactionMap.remove(temp);
        GlobalTransaction globalTransaction = (GlobalTransaction) globalTransactionMap.remove(tx);
        try {
          globalTransaction.rollback();
        } catch (Exception ignore) {
        }
      }
    }
  }

  class TransactionTimeOutThread implements Runnable {

    protected volatile boolean toContinueRunning = true;

    @Override
    public void run() {
      GlobalTransaction currentGtx = null;
      long lag = 0;
      LogWriter logger = TransactionUtils.getLogWriter();

      while (toContinueRunning) { // Asif :Ensure that we do not get out of
        try { // wait
          // without a GTX object
          synchronized (gtxSet) {
            while (gtxSet.isEmpty() && toContinueRunning) {
              gtxSet.wait();
            }
            if (!toContinueRunning)
              continue;
            currentGtx = (GlobalTransaction) gtxSet.first();
          }
          // Asif : Check whether current GTX has timed out or not
          boolean continueInner = true;
          do {
            synchronized (currentGtx) {
              lag = System.currentTimeMillis() - currentGtx.getExpirationTime();
              if (lag >= 0) {
                // Asif: Expire the GTX .Do not worry if some GTX comes
                // before it in Map , ie
                // even if there is a GTX earlier than this one to expire ,
                // it is OK
                // to first take care of this one
                // TODO: Do the clean up from all Maps
                currentGtx.expireGTX();
                gtxSet.remove(currentGtx);
              }
            }
            synchronized (gtxSet) {
              if (gtxSet.isEmpty()) {
                continueInner = false;
              } else {
                currentGtx = (GlobalTransaction) gtxSet.first();
                boolean isGTXExp = false;
                // Asif: There will not be any need for synchronizing
                // on currentGTX as we are already taking lokc on gtxSet.
                // Since the GTXSEt is locked that implies no GTX can be
                // either removed or added ( if already removed)
                // if the thread is in this block . thus we are safe
                //
                // synchronized (currentGtx) {
                lag = System.currentTimeMillis() - currentGtx.getExpirationTime();
                if (lag < 0) {
                  // Asif : Make the thread wait for stipluated
                  // time
                  isGTXExp = false;
                } else {
                  isGTXExp = true;
                  // Asif It is possibel that GTX is already expired but
                  // just got added in TreeSet bcoz of the small window
                  // in setTimeOut function of TranxnManager.
                  if (!currentGtx.isExpired()) {
                    currentGtx.expireGTX();
                  }
                  gtxSet.remove(currentGtx);
                  // Asif Clean the objects
                  if (gtxSet.isEmpty()) {
                    continueInner = false;
                  } else {
                    currentGtx = (GlobalTransaction) gtxSet.first();
                  }
                }
                // }
                // Asif : It is OK if we release the lock on Current GTX
                // for sleep
                // bcoz as we have still the the lock on gtxSet, even if
                // the
                // transaction set time out gets modified by other client
                // thread,
                // it will notbe added to the set as the lock is still
                // with us.
                // So in case of new tiemout value, if it is such that
                // the GTX is
                /// at the beginning , notified will be issued & the
                // cleaner thread
                // wil awake.
                // the set as the lock is
                if (!isGTXExp && toContinueRunning) {
                  gtxSet.wait(-(lag));
                  if (gtxSet.isEmpty()) {
                    continueInner = false;
                  } else {
                    currentGtx = (GlobalTransaction) gtxSet.first();
                  }
                }
                if (!toContinueRunning) {
                  continueInner = false;
                }
              }
            } // synchronized
          } while (continueInner);
        } catch (InterruptedException e) {
          // No need to reset the bit; we'll exit.
          if (toContinueRunning) {
            logger.fine("TransactionTimeOutThread: unexpected exception", e);
          }
          return;
        } catch (CancelException e) {
          // this thread is shutdown by doing an interrupt so this is expected
          // logger.fine("TransactionTimeOutThread: encountered exception", e);
          return;
        } catch (Exception e) {
          if (logger.severeEnabled() && toContinueRunning) {
            logger.severe(
                "Exception occurred while inspecting global transaction for expiry",
                e);
          }
        }
      }
    }
  }

  static class GlobalTransactionComparator implements Comparator, Serializable {

    /**
     * Sort the array in ascending order of expiration times
     */
    @Override
    public int compare(Object obj1, Object obj2) {
      GlobalTransaction gtx1 = (GlobalTransaction) obj1;
      GlobalTransaction gtx2 = (GlobalTransaction) obj2;
      return gtx1.compare(gtx2);
    }
  }

  /**
   * Shutdown the transactionManager and threads associated with this.
   */
  public static void refresh() {
    getTransactionManager();
    transactionManager.isActive = false;
    transactionManager.cleaner.toContinueRunning = false;
    try {
      transactionManager.cleanUpThread.interrupt();
    } catch (Exception e) {
      LogWriter writer = TransactionUtils.getLogWriter();
      if (writer.infoEnabled())
        writer.info(
            "Exception While cleaning thread before re startup");
    }
    /*
     * try { transactionManager.cleanUpThread.join(); } catch (Exception e) { e.printStackTrace(); }
     */
    transactionManager = null;
  }
}
