001: /**
002: *
003: * Licensed to the Apache Software Foundation (ASF) under one or more
004: * contributor license agreements. See the NOTICE file distributed with
005: * this work for additional information regarding copyright ownership.
006: * The ASF licenses this file to You under the Apache License, Version 2.0
007: * (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */package org.apache.openejb.core;
018:
019: import java.util.Map;
020: import java.util.HashMap;
021: import javax.transaction.Status;
022: import javax.transaction.Synchronization;
023: import javax.transaction.SystemException;
024: import javax.transaction.TransactionManager;
025: import javax.transaction.TransactionSynchronizationRegistry;
026: import javax.transaction.Transaction;
027:
028: public class SimpleTransactionSynchronizationRegistry implements
029: TransactionSynchronizationRegistry {
030: private final TransactionManager transactionManager;
031: private final Map<Transaction, Map<Object, Object>> transactionResources = new HashMap<Transaction, Map<Object, Object>>();
032:
033: public SimpleTransactionSynchronizationRegistry(
034: TransactionManager transactionManager) {
035: this .transactionManager = transactionManager;
036: }
037:
038: public Transaction getTransactionKey() {
039: try {
040: return transactionManager.getTransaction();
041: } catch (SystemException e) {
042: return null;
043: }
044: }
045:
046: public Object getResource(Object key) {
047: Transaction transaction = getActiveTransaction();
048:
049: Map<Object, Object> resources = transactionResources
050: .get(transaction);
051: if (resources == null) {
052: return null;
053: }
054:
055: Object value = resources.get(key);
056: return value;
057: }
058:
059: public void putResource(Object key, Object value) {
060: Transaction transaction = getActiveTransaction();
061:
062: Map<Object, Object> resources = transactionResources
063: .get(transaction);
064: if (resources == null) {
065: // after transaction completes clean up resources
066: try {
067: transaction
068: .registerSynchronization(new RemoveTransactionResources(
069: transaction));
070: } catch (Exception e) {
071: throw new IllegalStateException(
072: "No transaction active", e);
073: }
074: resources = new HashMap<Object, Object>();
075: transactionResources.put(transaction, resources);
076: }
077:
078: resources.put(key, value);
079: }
080:
081: public int getTransactionStatus() {
082: try {
083: return transactionManager.getStatus();
084: } catch (SystemException e) {
085: return Status.STATUS_NO_TRANSACTION;
086: }
087: }
088:
089: public void registerInterposedSynchronization(
090: Synchronization synchronization) {
091: if (synchronization == null) {
092: throw new NullPointerException("synchronization is null");
093: }
094:
095: Transaction transaction = getActiveTransaction();
096: try {
097: transaction.registerSynchronization(synchronization);
098: } catch (Exception ignored) {
099: }
100: }
101:
102: public boolean getRollbackOnly() {
103: Transaction transaction = getActiveTransaction();
104: try {
105: return transaction.getStatus() == Status.STATUS_MARKED_ROLLBACK;
106: } catch (Exception e) {
107: throw new IllegalStateException("No transaction active", e);
108: }
109: }
110:
111: public void setRollbackOnly() {
112: Transaction transaction = getActiveTransaction();
113: try {
114: transaction.setRollbackOnly();
115: } catch (Exception e) {
116: throw new IllegalStateException("No transaction active", e);
117: }
118: }
119:
120: private Transaction getActiveTransaction() {
121: try {
122: Transaction transaction = transactionManager
123: .getTransaction();
124: if (transaction == null) {
125: throw new IllegalStateException("No transaction active");
126: }
127: int status = transaction.getStatus();
128: if (status != Status.STATUS_ACTIVE
129: && status != Status.STATUS_MARKED_ROLLBACK) {
130: throw new IllegalStateException("No transaction active");
131: }
132: return transaction;
133: } catch (SystemException e) {
134: throw new IllegalStateException("No transaction active", e);
135: }
136: }
137:
138: private class RemoveTransactionResources implements Synchronization {
139: private final Transaction transaction;
140:
141: public RemoveTransactionResources(Transaction transaction) {
142: this .transaction = transaction;
143: }
144:
145: public void beforeCompletion() {
146: }
147:
148: public void afterCompletion(int i) {
149: transactionResources.remove(transaction);
150: }
151: }
152: }
|