]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.enterprise/src/org/argeo/osgi/useradmin/WcXaResource.java
[maven-release-plugin] prepare release v2.3.4
[lgpl/argeo-commons.git] / org.argeo.enterprise / src / org / argeo / osgi / useradmin / WcXaResource.java
1 package org.argeo.osgi.useradmin;
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 class WcXaResource implements XAResource {
12 private final AbstractUserDirectory userDirectory;
13
14 private Map<Xid, UserDirectoryWorkingCopy> workingCopies = new HashMap<Xid, UserDirectoryWorkingCopy>();
15 private Xid editingXid = null;
16 private int transactionTimeout = 0;
17
18 public WcXaResource(AbstractUserDirectory userDirectory) {
19 this.userDirectory = userDirectory;
20 }
21
22 @Override
23 public synchronized void start(Xid xid, int flags) throws XAException {
24 if (editingXid != null)
25 throw new UserDirectoryException("Already editing " + editingXid);
26 UserDirectoryWorkingCopy wc = workingCopies.put(xid, new UserDirectoryWorkingCopy());
27 if (wc != null)
28 throw new UserDirectoryException("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 UserDirectoryWorkingCopy wc(Xid xid) {
38 return workingCopies.get(xid);
39 }
40
41 synchronized UserDirectoryWorkingCopy wc() {
42 if (editingXid == null)
43 return null;
44 UserDirectoryWorkingCopy wc = workingCopies.get(editingXid);
45 if (wc == null)
46 throw new UserDirectoryException("No working copy found for " + editingXid);
47 return wc;
48 }
49
50 private synchronized void cleanUp(Xid xid) {
51 wc(xid).cleanUp();
52 workingCopies.remove(xid);
53 editingXid = null;
54 }
55
56 @Override
57 public int prepare(Xid xid) throws XAException {
58 checkXid(xid);
59 UserDirectoryWorkingCopy wc = wc(xid);
60 if (wc.noModifications())
61 return XA_RDONLY;
62 try {
63 userDirectory.prepare(wc);
64 } catch (Exception e) {
65 e.printStackTrace();
66 throw new XAException(XAException.XAER_RMERR);
67 }
68 return XA_OK;
69 }
70
71 @Override
72 public void commit(Xid xid, boolean onePhase) throws XAException {
73 try {
74 checkXid(xid);
75 UserDirectoryWorkingCopy wc = wc(xid);
76 if (wc.noModifications())
77 return;
78 if (onePhase)
79 userDirectory.prepare(wc);
80 userDirectory.commit(wc);
81 } catch (Exception e) {
82 e.printStackTrace();
83 throw new XAException(XAException.XAER_RMERR);
84 } finally {
85 cleanUp(xid);
86 }
87 }
88
89 @Override
90 public void rollback(Xid xid) throws XAException {
91 try {
92 checkXid(xid);
93 userDirectory.rollback(wc(xid));
94 } catch (Exception e) {
95 e.printStackTrace();
96 throw new XAException(XAException.XAER_RMERR);
97 } finally {
98 cleanUp(xid);
99 }
100 }
101
102 @Override
103 public void forget(Xid xid) throws XAException {
104 throw new UnsupportedOperationException();
105 }
106
107 @Override
108 public boolean isSameRM(XAResource xares) throws XAException {
109 return xares == this;
110 }
111
112 @Override
113 public Xid[] recover(int flag) throws XAException {
114 return new Xid[0];
115 }
116
117 @Override
118 public int getTransactionTimeout() throws XAException {
119 return transactionTimeout;
120 }
121
122 @Override
123 public boolean setTransactionTimeout(int seconds) throws XAException {
124 transactionTimeout = seconds;
125 return true;
126 }
127
128 private void checkXid(Xid xid) throws XAException {
129 if (xid == null)
130 throw new XAException(XAException.XAER_OUTSIDE);
131 if (!xid.equals(xid))
132 throw new XAException(XAException.XAER_NOTA);
133 }
134
135 }