]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.security.core/src/org/argeo/osgi/transaction/simple/SimpleTransactionManager.java
Continue framework clean up.
[lgpl/argeo-commons.git] / org.argeo.security.core / src / org / argeo / osgi / transaction / simple / SimpleTransactionManager.java
1 package org.argeo.osgi.transaction.simple;
2
3 import java.util.Collections;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import javax.transaction.HeuristicMixedException;
8 import javax.transaction.HeuristicRollbackException;
9 import javax.transaction.InvalidTransactionException;
10 import javax.transaction.NotSupportedException;
11 import javax.transaction.RollbackException;
12 import javax.transaction.Status;
13 import javax.transaction.Synchronization;
14 import javax.transaction.SystemException;
15 import javax.transaction.Transaction;
16 import javax.transaction.TransactionManager;
17 import javax.transaction.TransactionSynchronizationRegistry;
18 import javax.transaction.UserTransaction;
19 import javax.transaction.xa.Xid;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24 public class SimpleTransactionManager implements TransactionManager, UserTransaction {
25 private final static Log log = LogFactory.getLog(SimpleTransactionManager.class);
26
27 private ThreadLocal<SimpleTransaction> current = new ThreadLocal<SimpleTransaction>();
28
29 private Map<Xid, SimpleTransaction> knownTransactions = Collections
30 .synchronizedMap(new HashMap<Xid, SimpleTransaction>());
31 private SyncRegistry syncRegistry = new SyncRegistry();
32
33 @Override
34 public void begin() throws NotSupportedException, SystemException {
35 if (getCurrent() != null)
36 throw new NotSupportedException("Nested transactions are not supported");
37 SimpleTransaction transaction = new SimpleTransaction(this);
38 knownTransactions.put(transaction.getXid(), transaction);
39 current.set(transaction);
40 if (log.isDebugEnabled())
41 log.debug("STARTED " + transaction.getXid());
42 }
43
44 @Override
45 public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException,
46 SecurityException, IllegalStateException, SystemException {
47 if (getCurrent() == null)
48 throw new IllegalStateException("No transaction registered with the current thread.");
49 getCurrent().commit();
50 }
51
52 @Override
53 public int getStatus() throws SystemException {
54 if (getCurrent() == null)
55 return Status.STATUS_NO_TRANSACTION;
56 return getTransaction().getStatus();
57 }
58
59 @Override
60 public Transaction getTransaction() throws SystemException {
61 return getCurrent();
62 }
63
64 protected SimpleTransaction getCurrent() throws SystemException {
65 SimpleTransaction transaction = current.get();
66 if (transaction == null)
67 return null;
68 int status = transaction.getStatus();
69 if (Status.STATUS_COMMITTED == status || Status.STATUS_ROLLEDBACK == status) {
70 current.remove();
71 return null;
72 }
73 return transaction;
74 }
75
76 void unregister(Xid xid) {
77 knownTransactions.remove(xid);
78 }
79
80 @Override
81 public void resume(Transaction tobj) throws InvalidTransactionException, IllegalStateException, SystemException {
82 if (getCurrent() != null)
83 throw new IllegalStateException("Transaction " + current.get() + " already registered");
84 current.set((SimpleTransaction) tobj);
85 }
86
87 @Override
88 public void rollback() throws IllegalStateException, SecurityException, SystemException {
89 if (getCurrent() == null)
90 throw new IllegalStateException("No transaction registered with the current thread.");
91 getCurrent().rollback();
92 }
93
94 @Override
95 public void setRollbackOnly() throws IllegalStateException, SystemException {
96 if (getCurrent() == null)
97 throw new IllegalStateException("No transaction registered with the current thread.");
98 getCurrent().setRollbackOnly();
99 }
100
101 @Override
102 public void setTransactionTimeout(int seconds) throws SystemException {
103 throw new UnsupportedOperationException();
104 }
105
106 @Override
107 public Transaction suspend() throws SystemException {
108 Transaction transaction = getCurrent();
109 current.remove();
110 return transaction;
111 }
112
113 public TransactionSynchronizationRegistry getTsr() {
114 return syncRegistry;
115 }
116
117 private class SyncRegistry implements TransactionSynchronizationRegistry {
118 @Override
119 public Object getTransactionKey() {
120 try {
121 SimpleTransaction transaction = getCurrent();
122 if (transaction == null)
123 return null;
124 return getCurrent().getXid();
125 } catch (SystemException e) {
126 throw new RuntimeException("Cannot get transaction key", e);
127 }
128 }
129
130 @Override
131 public void putResource(Object key, Object value) {
132 throw new UnsupportedOperationException();
133 }
134
135 @Override
136 public Object getResource(Object key) {
137 throw new UnsupportedOperationException();
138 }
139
140 @Override
141 public void registerInterposedSynchronization(Synchronization sync) {
142 throw new UnsupportedOperationException();
143 }
144
145 @Override
146 public int getTransactionStatus() {
147 try {
148 return getStatus();
149 } catch (SystemException e) {
150 throw new RuntimeException("Cannot get status", e);
151 }
152 }
153
154 @Override
155 public boolean getRollbackOnly() {
156 try {
157 return getStatus() == Status.STATUS_MARKED_ROLLBACK;
158 } catch (SystemException e) {
159 throw new RuntimeException("Cannot get status", e);
160 }
161 }
162
163 @Override
164 public void setRollbackOnly() {
165 try {
166 getCurrent().setRollbackOnly();
167 } catch (Exception e) {
168 throw new RuntimeException("Cannot set rollback only", e);
169 }
170 }
171
172 }
173 }