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