001: /**
002: * Objective Database Abstraction Layer (ODAL)
003: * Copyright (c) 2004, The ODAL Development Group
004: * All rights reserved.
005: * For definition of the ODAL Development Group please refer to LICENCE.txt file
006: *
007: * Distributable under LGPL license.
008: * See terms of license at gnu.org.
009: */package com.completex.objective.components.persistency.transact.impl;
010:
011: import com.completex.objective.components.persistency.transact.Transaction;
012: import com.completex.objective.components.persistency.OdalRuntimePersistencyException;
013: import com.completex.objective.components.persistency.OdalNoTransactionException;
014:
015: import java.util.Stack;
016:
017: /**
018: * @author Gennady Krizhevsky
019: */
020: public class TransactionContainer extends ThreadLocal {
021:
022: private int maxNested = 2;
023:
024: public TransactionContainer() {
025: }
026:
027: public TransactionContainer(int maxNested) {
028: this .maxNested = maxNested;
029: }
030:
031: public int getMaxNested() {
032: return maxNested;
033: }
034:
035: protected void setMaxNested(int maxNested) {
036: this .maxNested = maxNested;
037: }
038:
039: public void validateTransactionForRelease(
040: Transaction transactionToRelease) {
041: Transaction transaction = peekTransaction();
042: if (!transactionToRelease.equals(transaction)) {
043: if (!contains(transactionToRelease)) {
044: throw new OdalRuntimePersistencyException(
045: "<<<BUG>>> transactionToRelease not in transaction stack");
046: }
047: throw new OdalRuntimePersistencyException(
048: "<<<BUG>>> transactionToRelease is not first in stack: nested transaction is being committed in wrong order");
049: }
050: }
051:
052: public Transaction peekTransaction() {
053: validateForNull();
054: return peek();
055: }
056:
057: public Transaction popTransaction() {
058: validateForNull();
059: return pop();
060: }
061:
062: public Transaction pushTransaction(Transaction transaction) {
063: validateForNull(transaction);
064: if (size() > maxNested) {
065: throw new OdalRuntimePersistencyException(
066: "Max size of nested transaction exceded allowed maximum ["
067: + maxNested + "]");
068: }
069: push(transaction);
070: return transaction;
071: }
072:
073: private void validateForNull(Transaction transaction) {
074: if (transaction == null) {
075: invalidateNoTransaction();
076: }
077: }
078:
079: private void validateForNull() {
080: if (isEmpty()) {
081: invalidateNoTransaction();
082: }
083: }
084:
085: private void invalidateNoTransaction() {
086: throw new OdalNoTransactionException(
087: "Transaction must be created first");
088: }
089:
090: protected Object initialValue() {
091: return new Stack();
092: }
093:
094: protected Transaction pop() {
095: Stack stack = (Stack) get();
096: return (Transaction) (stack).pop();
097: }
098:
099: protected Transaction peek() {
100: Stack stack = (Stack) get();
101: return (Transaction) (stack).peek();
102: }
103:
104: protected void push(Transaction transaction) {
105: Stack stack = (Stack) get();
106: (stack).push(transaction);
107: }
108:
109: public boolean isEmpty() {
110: Stack stack = (Stack) get();
111: return (stack).empty();
112: }
113:
114: public boolean contains(Transaction transaction) {
115: Stack stack = (Stack) get();
116: return (stack).contains(transaction);
117: }
118:
119: public int size() {
120: Stack stack = (Stack) get();
121: return stack.size();
122: }
123:
124: public String toString() {
125: return "TransactionContainer: currentTransaction : " + get();
126: }
127: }
|