]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/util/transaction/WorkingCopyXaResource.java
Introduce guided form to replace wizards
[lgpl/argeo-commons.git] / org.argeo.util / src / org / argeo / util / transaction / WorkingCopyXaResource.java
1 package org.argeo.util.transaction;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import javax.transaction.xa.XAException;
7 import javax.transaction.xa.XAResource;
8 import javax.transaction.xa.Xid;
9
10 /** {@link XAResource} for a user directory being edited. */
11 public class WorkingCopyXaResource<WC extends WorkingCopy<?, ?, ?>> implements XAResource {
12 private final WorkingCopyProcessor<WC> processor;
13
14 private Map<Xid, WC> workingCopies = new HashMap<Xid, WC>();
15 private Xid editingXid = null;
16 private int transactionTimeout = 0;
17
18 public WorkingCopyXaResource(WorkingCopyProcessor<WC> processor) {
19 this.processor = processor;
20 }
21
22 @Override
23 public synchronized void start(Xid xid, int flags) throws XAException {
24 if (editingXid != null)
25 throw new IllegalStateException("Already editing " + editingXid);
26 WC wc = workingCopies.put(xid, processor.newWorkingCopy());
27 if (wc != null)
28 throw new IllegalStateException("There is already a working copy for " + xid);
29 this.editingXid = xid;
30 }
31
32 @Override
33 public void end(Xid xid, int flags) throws XAException {
34 checkXid(xid);
35 }
36
37 private WC wc(Xid xid) {
38 return workingCopies.get(xid);
39 }
40
41 public synchronized WC wc() {
42 if (editingXid == null)
43 return null;
44 WC wc = workingCopies.get(editingXid);
45 if (wc == null)
46 throw new IllegalStateException("No working copy found for " + editingXid);
47 return wc;
48 }
49
50 private synchronized void cleanUp(Xid xid) {
51 WC wc = workingCopies.get(xid);
52 if (wc != null) {
53 wc.cleanUp();
54 workingCopies.remove(xid);
55 }
56 editingXid = null;
57 }
58
59 @Override
60 public int prepare(Xid xid) throws XAException {
61 checkXid(xid);
62 WC wc = wc(xid);
63 if (wc.noModifications())
64 return XA_RDONLY;
65 try {
66 processor.prepare(wc);
67 } catch (Exception e) {
68 e.printStackTrace();
69 throw new XAException(XAException.XAER_RMERR);
70 }
71 return XA_OK;
72 }
73
74 @Override
75 public void commit(Xid xid, boolean onePhase) throws XAException {
76 try {
77 checkXid(xid);
78 WC wc = wc(xid);
79 if (wc.noModifications())
80 return;
81 if (onePhase)
82 processor.prepare(wc);
83 processor.commit(wc);
84 } catch (Exception e) {
85 e.printStackTrace();
86 throw new XAException(XAException.XAER_RMERR);
87 } finally {
88 cleanUp(xid);
89 }
90 }
91
92 @Override
93 public void rollback(Xid xid) throws XAException {
94 try {
95 checkXid(xid);
96 processor.rollback(wc(xid));
97 } catch (Exception e) {
98 e.printStackTrace();
99 throw new XAException(XAException.XAER_RMERR);
100 } finally {
101 cleanUp(xid);
102 }
103 }
104
105 @Override
106 public void forget(Xid xid) throws XAException {
107 throw new UnsupportedOperationException();
108 }
109
110 @Override
111 public boolean isSameRM(XAResource xares) throws XAException {
112 return xares == this;
113 }
114
115 @Override
116 public Xid[] recover(int flag) throws XAException {
117 return new Xid[0];
118 }
119
120 @Override
121 public int getTransactionTimeout() throws XAException {
122 return transactionTimeout;
123 }
124
125 @Override
126 public boolean setTransactionTimeout(int seconds) throws XAException {
127 transactionTimeout = seconds;
128 return true;
129 }
130
131 private void checkXid(Xid xid) throws XAException {
132 if (xid == null)
133 throw new XAException(XAException.XAER_OUTSIDE);
134 if (!xid.equals(xid))
135 throw new XAException(XAException.XAER_NOTA);
136 }
137
138 }