Package org.openntf.domino.transactions

Source Code of org.openntf.domino.transactions.DatabaseTransaction

package org.openntf.domino.transactions;

import java.util.ArrayDeque;
import java.util.HashSet;
import java.util.Queue;
import java.util.Set;
import java.util.logging.Logger;

import org.openntf.domino.Agent;
import org.openntf.domino.Database;
import org.openntf.domino.Document;
import org.openntf.domino.Outline;
import org.openntf.domino.types.DatabaseDescendant;

public class DatabaseTransaction {
  private static final Logger log_ = Logger.getLogger(DatabaseTransaction.class.getName());

  //  private final Database database_;
  private final Set<Database> databases_ = new HashSet<Database>();
  private boolean isCommitting_ = false;
  private Queue<DatabaseDescendant> updateQueue_;
  private Queue<DatabaseDescendant> removeQueue_;

  public DatabaseTransaction(final org.openntf.domino.Database database) {
    databases_.add(database);
    //    database_ = database;
  }

  private boolean isDocLock(final DatabaseDescendant desc) {
    return desc.getAncestorDatabase().isDocumentLockingEnabled();
  }

  //  private boolean isDocLock() {
  //    return database_.isDocumentLockingEnabled();
  //  }

  private boolean isDesignLock(final DatabaseDescendant desc) {
    return desc.getAncestorDatabase().isDesignLockingEnabled();
    //    return database_.isDesignLockingEnabled();
  }

  //  private boolean isDesignLock() {
  //    return database_.isDesignLockingEnabled();
  //  }

  public int getUpdateSize() {
    return getUpdateQueue().size();
  }

  public int getRemoveSize() {
    return getRemoveQueue().size();
  }

  protected Queue<DatabaseDescendant> getUpdateQueue() {
    if (updateQueue_ == null) {
      updateQueue_ = new ArrayDeque<DatabaseDescendant>(); // TODO NTF - Switch to ArrayBlockingQueue and manage total
                                  // handles?
    }
    return updateQueue_;
  }

  protected Queue<DatabaseDescendant> getRemoveQueue() {
    if (removeQueue_ == null) {
      removeQueue_ = new ArrayDeque<DatabaseDescendant>(); // TODO NTF - Switch to ArrayBlockingQueue and manage total
                                  // handles?
    }
    return removeQueue_;
  }

  public void queueUpdate(final DatabaseDescendant base) {
    databases_.add(base.getAncestorDatabase());
    Queue<DatabaseDescendant> q = getUpdateQueue();
    //    synchronized (q) {
    q.add(base);
    //    }
    if (isDocLock(base) && base instanceof Document) {
      ((Document) base).lock();
    }
    if (isDesignLock(base)) {
      if (base instanceof Agent) {
        ((Agent) base).lock();
      } else if (base instanceof Outline) {
        // TODO - what? Outline doesn't have a .lock() method
      } else {
        // TODO - NTF build View/Form change transaction cache. Not fun. :-(
      }
    }
  }

  public void queueRemove(final DatabaseDescendant base) {
    databases_.add(base.getAncestorDatabase());
    Queue<DatabaseDescendant> q = getRemoveQueue();
    //    synchronized (q) {
    q.add(base);
    //    }
    if (isDocLock(base) && base instanceof Document) {
      ((Document) base).lock();
    }
    if (isDesignLock(base)) {
      if (base instanceof Agent) {
        ((Agent) base).lock();
      } else if (base instanceof Outline) {
        // TODO - what? Outline doesn't have a .lock() method
      } else {
        // TODO - NTF build View/Form change transaction cache. Not fun. :-(
      }
    }
  }

  // public boolean isCommitting() {
  // return isCommitting_;
  // }

  public void commit() {
    // System.out.println("Committing transaction with update size " + getUpdateQueue().size());
    isCommitting_ = true;
    Queue<DatabaseDescendant> uq = getUpdateQueue();
    //    synchronized (uq) {
    DatabaseDescendant next = uq.poll();
    while (next != null) {
      if (next instanceof Document) {
        boolean result = ((Document) next).save();
        if (!result) {
          // System.out.println("Transaction document save failed.");
          // TODO NTF - take some action to indicate that the save failed, potentially cancelling the transaction
        } else {
          if (isDocLock(next))
            ((Document) next).unlock();
        }
      }
      // TODO NTF - Implement other database objects
      next = uq.poll();
    }
    //    }
    Queue<DatabaseDescendant> rq = getRemoveQueue();
    //    synchronized (rq) {
    /*DatabaseDescendant*/next = rq.poll();
    while (next != null) {
      if (next instanceof org.openntf.domino.Document) {
        org.openntf.domino.Document doc = (org.openntf.domino.Document) next;
        if (isDocLock(doc))
          doc.unlock();
        doc.forceDelegateRemove();
      }
      // TODO NTF - Implement other database objects
      next = rq.poll();
    }
    //    }
    for (Database db : databases_) {
      db.closeTransaction();
    }
    //    database_.closeTransaction();
  }

  public void rollback() {
    // TODO - NTF release locks
    Queue<DatabaseDescendant> uq = getUpdateQueue();
    //    synchronized (uq) {
    DatabaseDescendant next = uq.poll();
    while (next != null) {
      if (next instanceof org.openntf.domino.Document) {
        org.openntf.domino.Document doc = (org.openntf.domino.Document) next;
        doc.rollback();
        if (isDocLock(doc)) {
          doc.unlock();
        }
      }
      // TODO NTF - Implement other database objects
      next = uq.poll();
    }
    //    }
    Queue<DatabaseDescendant> rq = getRemoveQueue();
    //    synchronized (rq) {
    /*DatabaseDescendant*/next = rq.poll();
    while (next != null) {
      if (next instanceof org.openntf.domino.Document) {
        org.openntf.domino.Document doc = (org.openntf.domino.Document) next;
        doc.rollback();
        if (isDocLock(doc))
          doc.unlock();
      }
      // TODO NTF - Implement other database objects
      next = rq.poll();
    }
    //    }
    for (Database db : databases_) {
      db.closeTransaction();
    }
  }

  private String getDbList() {
    StringBuilder sb = new StringBuilder();
    for (Database db : databases_) {
      sb.append(db.getApiPath());
      sb.append(',');
    }
    return sb.toString();
  }

  /* (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    return "DatabaseTransaction [databases=" + getDbList() + ", updateQueue_=" + (updateQueue_ == null ? "0" : updateQueue_.size())
        + ", removeQueue_=" + (removeQueue_ == null ? "0" : removeQueue_.size()) + "]";
  }

}
TOP

Related Classes of org.openntf.domino.transactions.DatabaseTransaction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.