]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.security.core/src/org/argeo/osgi/useradmin/UserDirectoryWorkingCopy.java
Can extends login credentials block.
[lgpl/argeo-commons.git] / org.argeo.security.core / src / org / argeo / osgi / useradmin / UserDirectoryWorkingCopy.java
1 package org.argeo.osgi.useradmin;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import javax.naming.directory.Attributes;
7 import javax.naming.ldap.LdapName;
8 import javax.transaction.xa.XAException;
9 import javax.transaction.xa.XAResource;
10 import javax.transaction.xa.Xid;
11
12 import org.apache.commons.logging.Log;
13 import org.apache.commons.logging.LogFactory;
14
15 import bitronix.tm.resource.ehcache.EhCacheXAResourceProducer;
16
17 /** {@link XAResource} for a user directory being edited. */
18 class UserDirectoryWorkingCopy implements XAResource {
19 private final static Log log = LogFactory
20 .getLog(UserDirectoryWorkingCopy.class);
21 private final String cacheName = getClass().getName();
22
23 private final AbstractUserDirectory userDirectory;
24
25 private Xid xid;
26 private int transactionTimeout = 0;
27
28 private Map<LdapName, DirectoryUser> newUsers = new HashMap<LdapName, DirectoryUser>();
29 private Map<LdapName, Attributes> modifiedUsers = new HashMap<LdapName, Attributes>();
30 private Map<LdapName, DirectoryUser> deletedUsers = new HashMap<LdapName, DirectoryUser>();
31
32 public UserDirectoryWorkingCopy(AbstractUserDirectory userDirectory) {
33 this.userDirectory = userDirectory;
34 try {
35 // FIXME Make it less bitronix dependant
36 EhCacheXAResourceProducer.registerXAResource(cacheName, this);
37 } catch (Exception e) {
38 log.error("Cannot register resource to Bitronix", e);
39 }
40 }
41
42 @Override
43 public void start(Xid xid, int flags) throws XAException {
44 this.xid = xid;
45 }
46
47 @Override
48 public void end(Xid xid, int flags) throws XAException {
49 checkXid(xid);
50
51 }
52
53 private void cleanUp() {
54 // clean collections
55 newUsers.clear();
56 newUsers = null;
57 modifiedUsers.clear();
58 modifiedUsers = null;
59 deletedUsers.clear();
60 deletedUsers = null;
61
62 // clean IDs
63 this.xid = null;
64 userDirectory.clearEditingTransactionXid();
65
66 try {
67 // FIXME Make it less bitronix dependant
68 EhCacheXAResourceProducer.unregisterXAResource(cacheName, this);
69 } catch (Exception e) {
70 log.error("Cannot unregister resource from Bitronix", e);
71 }
72 }
73
74 @Override
75 public int prepare(Xid xid) throws XAException {
76 checkXid(xid);
77 if (noModifications())
78 return XA_RDONLY;
79 try {
80 userDirectory.prepare(this);
81 } catch (Exception e) {
82 log.error("Cannot prepare " + xid, e);
83 throw new XAException(XAException.XA_RBOTHER);
84 }
85 return XA_OK;
86 }
87
88 @Override
89 public void commit(Xid xid, boolean onePhase) throws XAException {
90 try {
91 checkXid(xid);
92 if (noModifications())
93 return;
94 if (onePhase)
95 userDirectory.prepare(this);
96 userDirectory.commit(this);
97 } catch (Exception e) {
98 log.error("Cannot commit " + xid, e);
99 throw new XAException(XAException.XA_RBOTHER);
100 } finally {
101 cleanUp();
102 }
103 }
104
105 @Override
106 public void rollback(Xid xid) throws XAException {
107 try {
108 checkXid(xid);
109 userDirectory.rollback(this);
110 } catch (Exception e) {
111 log.error("Cannot rollback " + xid, e);
112 throw new XAException(XAException.XA_HEURMIX);
113 } finally {
114 cleanUp();
115 }
116 }
117
118 @Override
119 public void forget(Xid xid) throws XAException {
120 throw new UnsupportedOperationException();
121 }
122
123 @Override
124 public boolean isSameRM(XAResource xares) throws XAException {
125 return xares == this;
126 }
127
128 @Override
129 public Xid[] recover(int flag) throws XAException {
130 return new Xid[0];
131 }
132
133 @Override
134 public int getTransactionTimeout() throws XAException {
135 return transactionTimeout;
136 }
137
138 @Override
139 public boolean setTransactionTimeout(int seconds) throws XAException {
140 transactionTimeout = seconds;
141 return true;
142 }
143
144 Xid getXid() {
145 return xid;
146 }
147
148 private void checkXid(Xid xid) throws XAException {
149 if (this.xid == null)
150 throw new XAException(XAException.XAER_OUTSIDE);
151 if (!this.xid.equals(xid))
152 throw new XAException(XAException.XAER_NOTA);
153 }
154
155 public boolean noModifications() {
156 return newUsers.size() == 0 && modifiedUsers.size() == 0
157 && deletedUsers.size() == 0;
158 }
159
160 public Attributes getAttributes(LdapName dn) {
161 if (modifiedUsers.containsKey(dn))
162 return modifiedUsers.get(dn);
163 return null;
164 }
165
166 public void startEditing(DirectoryUser user) {
167 LdapName dn = user.getDn();
168 if (modifiedUsers.containsKey(dn))
169 throw new UserDirectoryException("Already editing " + dn);
170 modifiedUsers.put(dn, (Attributes) user.getAttributes().clone());
171 }
172
173 public Map<LdapName, DirectoryUser> getNewUsers() {
174 return newUsers;
175 }
176
177 public Map<LdapName, DirectoryUser> getDeletedUsers() {
178 return deletedUsers;
179 }
180
181 public Map<LdapName, Attributes> getModifiedUsers() {
182 return modifiedUsers;
183 }
184
185 }