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