View Javadoc
1   package org.argeo.cms.ui.workbench.internal.useradmin;
2   
3   import java.util.ArrayList;
4   import java.util.Dictionary;
5   import java.util.HashMap;
6   import java.util.List;
7   import java.util.Map;
8   
9   import javax.transaction.Status;
10  import javax.transaction.UserTransaction;
11  
12  import org.argeo.cms.CmsException;
13  import org.argeo.node.NodeConstants;
14  import org.argeo.osgi.useradmin.UserAdminConf;
15  import org.osgi.framework.ServiceReference;
16  import org.osgi.service.useradmin.UserAdmin;
17  import org.osgi.service.useradmin.UserAdminEvent;
18  import org.osgi.service.useradmin.UserAdminListener;
19  
20  /** Centralise interaction with the UserAdmin in this bundle */
21  public class UserAdminWrapper {
22  
23  	private UserAdmin userAdmin;
24  	private ServiceReference<UserAdmin> userAdminServiceReference;
25  	private UserTransaction userTransaction;
26  
27  	// First effort to simplify UX while managing users and groups
28  	public final static boolean COMMIT_ON_SAVE = true;
29  
30  	// Registered listeners
31  	List<UserAdminListener> listeners = new ArrayList<UserAdminListener>();
32  
33  	/**
34  	 * Starts a transaction if necessary. Should always been called together
35  	 * with {@link UserAdminWrapper#commitOrNotifyTransactionStateChange()} once
36  	 * the security model changes have been performed.
37  	 */
38  	public UserTransaction beginTransactionIfNeeded() {
39  		try {
40  			// UserTransaction userTransaction = getUserTransaction();
41  			if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION) {
42  				userTransaction.begin();
43  				// UiAdminUtils.notifyTransactionStateChange(userTransaction);
44  			}
45  			return userTransaction;
46  		} catch (Exception e) {
47  			throw new CmsException("Unable to begin transaction", e);
48  		}
49  	}
50  
51  	/**
52  	 * Depending on the current application configuration, it will either commit
53  	 * the current transaction or throw a notification that the transaction
54  	 * state has changed (In the later case, it must be called from the UI
55  	 * thread).
56  	 */
57  	public void commitOrNotifyTransactionStateChange() {
58  		try {
59  			// UserTransaction userTransaction = getUserTransaction();
60  			if (userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION)
61  				return;
62  
63  			if (UserAdminWrapper.COMMIT_ON_SAVE)
64  				userTransaction.commit();
65  			else
66  				UiAdminUtils.notifyTransactionStateChange(userTransaction);
67  		} catch (Exception e) {
68  			throw new CmsException("Unable to clean transaction", e);
69  		}
70  	}
71  
72  	// TODO implement safer mechanism
73  	public void addListener(UserAdminListener userAdminListener) {
74  		if (!listeners.contains(userAdminListener))
75  			listeners.add(userAdminListener);
76  	}
77  
78  	public void removeListener(UserAdminListener userAdminListener) {
79  		if (listeners.contains(userAdminListener))
80  			listeners.remove(userAdminListener);
81  	}
82  
83  	public void notifyListeners(UserAdminEvent event) {
84  		for (UserAdminListener listener : listeners)
85  			listener.roleChanged(event);
86  	}
87  
88  	public Map<String, String> getKnownBaseDns(boolean onlyWritable) {
89  		Map<String, String> dns = new HashMap<String, String>();
90  		for (String uri : userAdminServiceReference.getPropertyKeys()) {
91  			if (!uri.startsWith("/"))
92  				continue;
93  			Dictionary<String, ?> props = UserAdminConf.uriAsProperties(uri);
94  			String readOnly = UserAdminConf.readOnly.getValue(props);
95  			String baseDn = UserAdminConf.baseDn.getValue(props);
96  
97  			if (onlyWritable && "true".equals(readOnly))
98  				continue;
99  			if (baseDn.equalsIgnoreCase(NodeConstants.ROLES_BASEDN))
100 				continue;
101 			dns.put(baseDn, uri);
102 		}
103 		return dns;
104 	}
105 
106 	public UserAdmin getUserAdmin() {
107 		return userAdmin;
108 	}
109 
110 	public UserTransaction getUserTransaction() {
111 		return userTransaction;
112 	}
113 
114 	/* DEPENDENCY INJECTION */
115 	public void setUserAdmin(UserAdmin userAdmin) {
116 		this.userAdmin = userAdmin;
117 	}
118 
119 	public void setUserTransaction(UserTransaction userTransaction) {
120 		this.userTransaction = userTransaction;
121 	}
122 
123 	public void setUserAdminServiceReference(
124 			ServiceReference<UserAdmin> userAdminServiceReference) {
125 		this.userAdminServiceReference = userAdminServiceReference;
126 	}
127 }