1 package org
.argeo
.osgi
.useradmin
;
3 import java
.util
.HashMap
;
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
;
12 import org
.apache
.commons
.logging
.Log
;
13 import org
.apache
.commons
.logging
.LogFactory
;
15 import bitronix
.tm
.resource
.ehcache
.EhCacheXAResourceProducer
;
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();
23 private final AbstractUserDirectory userDirectory
;
26 private int transactionTimeout
= 0;
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
>();
32 public UserDirectoryWorkingCopy(AbstractUserDirectory userDirectory
) {
33 this.userDirectory
= userDirectory
;
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
);
43 public void start(Xid xid
, int flags
) throws XAException
{
48 public void end(Xid xid
, int flags
) throws XAException
{
53 private void cleanUp() {
57 modifiedUsers
.clear();
64 userDirectory
.clearEditingTransactionXid();
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
);
75 public int prepare(Xid xid
) throws XAException
{
77 if (noModifications())
80 userDirectory
.prepare(this);
81 } catch (Exception e
) {
82 log
.error("Cannot prepare " + xid
, e
);
83 throw new XAException(XAException
.XA_RBOTHER
);
89 public void commit(Xid xid
, boolean onePhase
) throws XAException
{
92 if (noModifications())
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
);
106 public void rollback(Xid xid
) throws XAException
{
109 userDirectory
.rollback(this);
110 } catch (Exception e
) {
111 log
.error("Cannot rollback " + xid
, e
);
112 throw new XAException(XAException
.XA_HEURMIX
);
119 public void forget(Xid xid
) throws XAException
{
120 throw new UnsupportedOperationException();
124 public boolean isSameRM(XAResource xares
) throws XAException
{
125 return xares
== this;
129 public Xid
[] recover(int flag
) throws XAException
{
134 public int getTransactionTimeout() throws XAException
{
135 return transactionTimeout
;
139 public boolean setTransactionTimeout(int seconds
) throws XAException
{
140 transactionTimeout
= seconds
;
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
);
155 public boolean noModifications() {
156 return newUsers
.size() == 0 && modifiedUsers
.size() == 0
157 && deletedUsers
.size() == 0;
160 public Attributes
getAttributes(LdapName dn
) {
161 if (modifiedUsers
.containsKey(dn
))
162 return modifiedUsers
.get(dn
);
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());
173 public Map
<LdapName
, DirectoryUser
> getNewUsers() {
177 public Map
<LdapName
, DirectoryUser
> getDeletedUsers() {
181 public Map
<LdapName
, Attributes
> getModifiedUsers() {
182 return modifiedUsers
;