1
/** BEGIN COPYRIGHT BLOCK
2
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
3
* Copyright (C) 2005 Red Hat, Inc.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
* END COPYRIGHT BLOCK **/
20
package com.netscape.admin.dirserv.roledit;
24
import java.awt.event.*;
26
import javax.swing.table.*;
27
import javax.swing.event.*;
28
import com.netscape.management.client.console.ConsoleInfo;
29
import com.netscape.management.client.util.*;
30
import com.netscape.admin.dirserv.DSResourceEditor;
31
import com.netscape.management.nmclf.SuiLookAndFeel;
32
import com.netscape.admin.dirserv.IDSModel;
33
import com.netscape.admin.dirserv.DSUtil;
34
import netscape.ldap.*;
35
import netscape.ldap.util.DN;
39
* The dialog which displays the roles associated to an LDAP entry.
42
public class RoleEditorDialog extends AbstractDialog
43
implements ActionListener, ListSelectionListener {
47
* Construct an new RoleEditorDialog.
48
* The target LDAP entry is specified by info.getCurrentDN().
50
public RoleEditorDialog(JFrame frame, ConsoleInfo info) {
51
super(frame, _resource.getString(_section, "title", info.getCurrentDN() ), true, OK|CANCEL|HELP);
52
getAccessibleContext().setAccessibleDescription(_resource.getString(_section, "description"));
56
_managedRoleCache = new RoleCache(true);
57
_complexRoleCache = new RoleCache(true);
59
_tabPane = new JTabbedPane();
60
_managedRoleTab = new RoleEditorTab(true);
61
_managedRoleTab.getAddButton().addActionListener(this);
62
_managedRoleTab.getAddButton().getAccessibleContext().setAccessibleDescription(_managedRoleTab.getAddButton().getText());
63
_managedRoleTab.getRemoveButton().addActionListener(this);
64
_managedRoleTab.getRemoveButton().getAccessibleContext().setAccessibleDescription(_managedRoleTab.getRemoveButton().getText());
65
_managedRoleTab.getEditButton().addActionListener(this);
66
_managedRoleTab.getEditButton().getAccessibleContext().setAccessibleDescription(_managedRoleTab.getEditButton().getText());
67
_managedRoleTab.getTableSelectionModel().addListSelectionListener(this);
68
_complexRoleTab = new RoleEditorTab(false);
69
_complexRoleTab.getEditButton().addActionListener(this);
70
_complexRoleTab.getEditButton().getAccessibleContext().setAccessibleDescription(_complexRoleTab.getEditButton().getText());
71
_complexRoleTab.getTableSelectionModel().addListSelectionListener(this);
79
* Assemble and layout the components
81
void layoutComponents() {
82
Container contentPane = getContentPane();
83
GridBagLayout gbl = new GridBagLayout();
85
contentPane.setLayout(gbl);
87
GridBagConstraints gbc = new GridBagConstraints() ;
94
gbc.anchor = gbc.CENTER;
96
gbc.insets = new Insets(0, 0, 0, 0);
100
contentPane.add(_tabPane) ;
101
gbl.setConstraints(_tabPane, gbc);
103
_tabPane.addTab(_resource.getString(_section, "tab-managed-roles"), _managedRoleTab);
104
_managedRoleTab.getTable().getAccessibleContext().setAccessibleDescription(_resource.getString(_section,
105
"tab-managed-roles"));
106
_tabPane.addTab(_resource.getString(_section, "tab-complex-roles"), _complexRoleTab);
107
_complexRoleTab.getTable().getAccessibleContext().setAccessibleDescription(_resource.getString(_section,
108
"tab-complex-roles"));
109
_tabPane.setSelectedIndex(0);
117
* Implements ActionListener.
118
* Here we process clicks from both _managedRoleTab and _complexRoleTab.
120
public void actionPerformed(ActionEvent e) {
122
Object source = e.getSource();
124
if (source == _managedRoleTab.getEditButton()) {
125
int roleIndex = _managedRoleTab.getTableSelectionModel().getMinSelectionIndex();
126
actionEdit(_managedRoleCache, roleIndex);
128
else if (source == _managedRoleTab.getAddButton()) {
131
else if (source == _managedRoleTab.getRemoveButton()) {
134
else if (source == _complexRoleTab.getEditButton()) {
135
int roleIndex = _complexRoleTab.getTableSelectionModel().getMinSelectionIndex();
136
actionEdit(_complexRoleCache, roleIndex);
138
setBusyCursor(false);
143
* Process a click on Add.
146
Vector selectedRoles = null;
149
// Popup the role picker.
150
// The picker is instructed to show only managed roles.
153
String parentDn = RolePickerDialog.makeParentDn(_info.getCurrentDN());
154
RolePickerDialog picker;
155
picker = new RolePickerDialog(_frame, _info);
156
Enumeration exclude = _managedRoleCache.getRoleDNs().elements();
157
picker.load(parentDn, "nsmanagedroledefinition", exclude);
159
if (!picker.isCancel())
160
selectedRoles = picker.getSelectedRoles();
162
catch(LDAPException e) {
163
Debug.println("RoleEditorDialog.actionAdd: reading roles failed with " + e);
164
// We popup a dialog to warn the user
165
DSUtil.showLDAPErrorDialog(_frame, e, "fetching-server-unavailable");
169
// Adds the selected roles in _managedRoleCache.
170
// We must check that a role is not already included.
172
if (selectedRoles != null) {
174
LDAPConnection ldc = _info.getLDAPConnection();
175
Enumeration e = selectedRoles.elements();
176
while (e.hasMoreElements()) {
177
String roleDn = (String)e.nextElement();
178
DN roleDN = new DN(roleDn);
179
if ( !_managedRoleCache.contains(roleDN) )
180
_managedRoleCache.add(roleDn, ldc);
183
catch(LDAPException e) {
184
Debug.println("RoleEditorDialog.actionAdd: reading roles failed with " + e);
185
// We popup a dialog to warn the user
186
DSUtil.showLDAPErrorDialog(_frame, e,
187
"updating-directory-title");
195
* Process a click on Remove.
197
void actionRemove() {
198
JTable table = _managedRoleTab.getTable();
199
int managedRoleCount = table.getModel().getRowCount();
200
ListSelectionModel selModel = table.getSelectionModel();
202
for (int i = 0; i < managedRoleCount; i++) {
203
if (selModel.isSelectedIndex(i)) {
204
_managedRoleCache.remove(i);
212
* Process a click on Edit.
214
void actionEdit(RoleCache roleCache, int roleIndex) {
215
LDAPConnection ldc = _info.getLDAPConnection();
216
String roleDN = roleCache.getRoleDN(roleIndex);
219
// Read all the attributes of the roles and the nsroledn attribute
220
String[] attrs = {NSROLEDN_ATTR, "*"};
221
LDAPEntry entry = DSUtil.readEntry(ldc, roleDN, attrs, null);
223
// Open the resource editor on the selected entry
224
DSResourceEditor ed = new DSResourceEditor(_frame, _info, entry );
226
DSUtil.dialogCleanup();
228
// The user may change the role definition.
229
// So we ask the role cache to resync.
230
String newDN = ed.getLDAPEntry().getDN();
231
if (roleDN.equals(newDN)) { // The role DN didn't change
232
roleCache.sync(roleDN, ldc); // Synchronize the description
234
else { // The role DN has been changed.
235
// We update the cache by removing the old and adding the new.
236
roleCache.remove(roleDN);
237
roleCache.add(newDN, ldc);
240
catch(LDAPException e) {
241
// Explain to the user that the role does not exist
242
Debug.println("RoleEditorDialog.actionEdit: " + roleDN + " is obsolete");
243
JOptionPane.showMessageDialog(this,
244
_resource.getString(_section, "dangling-role-message"),
245
_resource.getString(_section, "dangling-role-title"),
246
JOptionPane.ERROR_MESSAGE);
253
* Implements ListSelectionListener.
254
* Called when the user clicks in the table.
255
* We update the tooltip text.
257
public void valueChanged(ListSelectionEvent e) {
258
ListSelectionModel m = (ListSelectionModel)e.getSource() ;
260
// Find the table and role cache associated to m
262
RoleCache roleCache ;
263
if (m == _managedRoleTab.getTableSelectionModel()) {
264
table = _managedRoleTab.getTable();
265
roleCache = _managedRoleCache;
268
table = _complexRoleTab.getTable();
269
roleCache = _complexRoleCache;
272
// Update the tooltip text of the tab
273
int min = m.getMinSelectionIndex() ;
274
int max = m.getMaxSelectionIndex() ;
275
if ((min == -1) || (max - min + 1 > 1) || roleCache.isEmpty()) {
276
// The selection is empty or multiple
277
table.setToolTipText(null);
280
table.setToolTipText(roleCache.getRoleDN(min));
286
* Overrides AbstractDialog.
287
* When OK is clicked, we save the role cache if it is dirty.
289
protected void okInvoked() {
290
String entryDn = _info.getCurrentDN();
291
if (_managedRoleCache.isRecordingEmpty()) { // Nothing changed
296
_managedRoleCache.saveRecording(entryDn, _info.getLDAPConnection());
299
catch(LDAPException e) {
300
// Explain to the user that something is going wrong.
301
Debug.println("RoleEditorDialog.okInvoked: failed to change roles of "
303
// We popup a dialog to warn the user
304
DSUtil.showLDAPErrorDialog(_frame, e,
305
"updating-directory-title");
312
* Overrides AbstractDialog.
314
protected void helpInvoked() {
315
DSUtil.help("configuration-set-role");
320
* Load the role caches.
321
* Here we read the nsrole and nsroledn attributes of the entry and
322
* dispatch the values between _managedRoleCache and _complexRoleCache.
324
void loadRoleCaches() {
326
String targetDn = _info.getCurrentDN();
327
String debugLabel = "RoleEditorDialog.loadRoleCaches(" + targetDn + "): ";
330
LDAPConnection ldc = _info.getLDAPConnection();
334
// Read the managed role entries
336
LDAPEntry entry = DSUtil.readEntry(ldc, targetDn, ROLE_ATTRS, null);
337
LDAPAttribute nsRoleDN = entry.getAttribute(NSROLEDN_ATTR);
338
if (nsRoleDN != null) {
339
Enumeration e = nsRoleDN.getStringValues();
342
while (e.hasMoreElements()) {
343
String roleDN = (String)e.nextElement();
344
_managedRoleCache.add(roleDN, ldc);
348
Debug.println(0, debugLabel + "getStringValues(" + NSROLEDN_ATTR + ") returned an empty Enumeration !");
352
Debug.println(0, debugLabel + "getStringValues(" + NSROLEDN_ATTR + ") returned null !");
356
Debug.println(debugLabel + "no " + NSROLEDN_ATTR + " attribute");
360
// Read the complex role entries
362
LDAPAttribute nsRole = entry.getAttribute(NSROLE_ATTR);
363
if (nsRole != null) {
364
Enumeration e = nsRole.getStringValues();
367
while (e.hasMoreElements()) {
368
String roleDN = (String)e.nextElement();
369
LDAPEntry roleEntry = DSUtil.readEntry(ldc, roleDN, BASIC_ATTRS, null);
370
if (roleEntry == null) {
371
Debug.println(0, debugLabel + " readEntry(" + roleDN + ") returned null !");
373
// nsrole includes the managed roles
374
// We keep only the complex roles.
375
else if (isComplexRole(roleEntry)) {
376
_complexRoleCache.add(roleEntry);
381
Debug.println(0, debugLabel + "getStringValues(" + NSROLE_ATTR + ") returned an empty Enumeration !");
385
Debug.println(0, debugLabel + "getStringValues(" + NSROLE_ATTR + ") returned NULL !");
389
Debug.println(debugLabel + "no " + NSROLE_ATTR + " attribute");
393
catch(LDAPException e) {
394
Debug.println(0, debugLabel + "exception " + e);
395
Debug.println(0, debugLabel + "no roles have been loaded");
398
// Update the table model of the panes
399
// If the loading has failed, the table models will be empty.
400
_managedRoleTab.getTable().setModel(_managedRoleCache.getTableModel());
401
_complexRoleTab.getTable().setModel(_complexRoleCache.getTableModel());
403
// Now we record any changes in _managedRoleCache.
404
_managedRoleCache.enableRecording(true);
409
* Return true if entry is an nscomplexroledefinition instance.
411
static boolean isComplexRole(LDAPEntry entry) {
412
boolean yes = false ;
414
LDAPAttribute objectClass = entry.getAttribute("objectclass");
415
if (objectClass == null) {
416
Debug.println(0, "RoleEditorDialog.isComplexRole: cannot find objectclass !");
419
Enumeration e = objectClass.getStringValues();
420
while (e.hasMoreElements() && !yes) {
421
String c = (String)e.nextElement() ;
422
yes = c.equalsIgnoreCase("nscomplexroledefinition");
433
RoleCache _managedRoleCache;
434
RoleCache _complexRoleCache;
437
JTabbedPane _tabPane;
438
RoleEditorTab _managedRoleTab;
439
RoleEditorTab _complexRoleTab;
442
static private final ResourceSet _resource = DSUtil._resource;
443
static private final String _section = "roleEditorDialog";
446
private static final String NSROLEDN_ATTR = "nsRoleDN";
447
private static final String NSROLE_ATTR = "nsRole";
448
// NOTE: I added objectclass in ROLE_ATTRS to workaround the
449
// server bug 393670.
450
private static final String[] ROLE_ATTRS = { "objectclass", NSROLEDN_ATTR, NSROLE_ATTR };
451
private static final String CN_ATTR = "cn";
452
private static final String DESCRIPTION_ATTR = "description";
453
private static final String OBJECTCLASS_ATTR = "objectclass";
454
private static final String[] BASIC_ATTRS = {CN_ATTR, DESCRIPTION_ATTR, OBJECTCLASS_ATTR};