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.event.*;
27
import javax.swing.text.*;
28
import com.netscape.management.nmclf.*;
29
import com.netscape.management.client.console.*;
30
import com.netscape.management.client.util.*;
31
import com.netscape.management.client.ug.*;
32
import netscape.ldap.*;
33
import netscape.ldap.util.DN;
34
import com.netscape.admin.dirserv.DSUtil;
35
import com.netscape.admin.dirserv.panel.UIFactory;
38
* ResEditorNestedRole is a plugin for the ResourceEditor.
39
* It is used to edit information specific to nsnesteddroledefinition entries.
41
public class ResEditorNestedRole extends JPanel
42
implements IResourceEditorPage,
45
ListSelectionListener {
49
public ResEditorNestedRole() {
50
_id = _resource.getString(_section, "id");
55
* Implements the Observer interface.
57
public void update(Observable o, Object arg) {
58
if ((o instanceof ResourcePageObservable) == false) {
61
ResourcePageObservable observable = (ResourcePageObservable) o;
62
if (arg instanceof String) {
63
String argString = (String) arg;
64
if (argString.equalsIgnoreCase(NSROLEDN_ATTR)) {
72
* Implements the IResourceEditorPage interface.
73
* Here we build the UI components, search roles from the directory
74
* and initialize the UI components with them.
76
public void initialize(ResourcePageObservable observable,
77
ResourceEditor parent) {
79
_observable = observable;
80
_roleCache = new RoleCache(true);
82
// Build and layout the components if not already done
84
JLabel label = new JLabel(_resource.getString(_section, "label"));
86
_table = new SuiTable();
87
label.setLabelFor(_table);
88
_table.setModel(_roleCache.getTableModel());
89
_table.setAutoResizeMode(_table.AUTO_RESIZE_ALL_COLUMNS);
90
_table.getSelectionModel().addListSelectionListener(this);
91
_table.setPreferredScrollableViewportSize(new Dimension(10, 10));
92
JScrollPane scrollPane = SuiTable.createScrollPaneForTable(_table);
93
scrollPane.setBorder(UIManager.getBorder("Table.scrollPaneBorder"));
95
_addButton = UIFactory.makeJButton( this, _section, "addButton", _resource);
96
_removeButton = UIFactory.makeJButton( this, _section, "removeButton", _resource);
98
JButtonFactory.resizeGroup(_addButton, _removeButton);
100
Box buttonBox = new Box(BoxLayout.X_AXIS);
101
buttonBox.add(Box.createHorizontalGlue());
102
buttonBox.add(_addButton);
103
buttonBox.add(Box.createHorizontalStrut(SuiLookAndFeel.SEPARATED_COMPONENT_SPACE));
104
buttonBox.add(_removeButton);
106
setLayout(new GridBagLayout());
107
GridBagUtil.constrain(this, label,
109
1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
110
SuiLookAndFeel.VERT_WINDOW_INSET, SuiLookAndFeel.HORIZ_WINDOW_INSET,
111
0, SuiLookAndFeel.HORIZ_WINDOW_INSET);
112
GridBagUtil.constrain(this, scrollPane,
114
1.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.BOTH,
115
0, SuiLookAndFeel.HORIZ_WINDOW_INSET,
116
0, SuiLookAndFeel.HORIZ_WINDOW_INSET);
117
GridBagUtil.constrain(this, buttonBox,
119
0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE,
120
SuiLookAndFeel.SEPARATED_COMPONENT_SPACE, SuiLookAndFeel.COMPONENT_SPACE,
121
SuiLookAndFeel.VERT_WINDOW_INSET, SuiLookAndFeel.HORIZ_WINDOW_INSET);
124
// Load values from the observable
126
valueChanged(null); // To update the state of _removeButton
131
* Load the nested roles in the cache.
139
_roleCache.enableRecording(false);
142
// Fill the cache with the roles in the nsroledn attribute of the entry.
145
LDAPConnection ldc = _parent.getConsoleInfo().getLDAPConnection();
146
Vector roleDNs = _observable.get(NSROLEDN_ATTR);
147
Enumeration e = roleDNs.elements() ;
148
while (e.hasMoreElements()) {
149
String dn = (String)e.nextElement();
150
_roleCache.add(dn, ldc);
153
catch(LDAPException e) {
154
Debug.println("ResEditorNestedRole.loadCache: " + e + " while loading the roles");
156
_roleCache.enableRecording(true);
161
* Implements the IResourceEditorPage interface.
163
public String getID() {
169
* Implements the IResourceEditorPage interface.
170
* We have nothing to do here.
172
public boolean afterSave(ResourcePageObservable observable) throws Exception {
178
* Implements the IResourceEditorPage interface.
179
* Save the list of nested roles (if modified) in the observable object.
181
public boolean save(ResourcePageObservable observable) throws Exception {
183
if (!_roleCache.isRecordingEmpty()) {
184
Vector roleDNs = _roleCache.getRoleDNs();
185
if (roleDNs == null) {
186
_observable.delete(NSROLEDN_ATTR) ;
189
_observable.replace(NSROLEDN_ATTR, roleDNs);
191
_roleCache.enableRecording(false);
192
_roleCache.enableRecording(true); // This clears the change records
200
* Implements the IResourceEditorPage interface.
202
public void clear() {
207
* Implements the IResourceEditorPage interface.
209
public void reset() {
214
* Implements the IResourceEditorPage interface.
216
public void setDefault() {
221
* Implements the IResourceEditorPage interface.
222
* Check if some changes have been recorded in the role cache.
224
public boolean isModified() {
225
return !_roleCache.isRecordingEmpty();
230
* Implements the IResourceEditorPage interface.
231
* Problem here: the 'modified' state is controled only
234
public void setModified(boolean value) {
236
throw new IllegalArgumentException("Can't set to true");
241
* Implements the IResourceEditorPage interface.
243
public boolean isReadOnly() {
249
* Implements the IResourceEditorPage interface.
251
public void setReadOnly(boolean value) {
257
* Implements the IResourceEditorPage interface.
259
public void setEnable(boolean value) {
265
* Implements the IResourceEditorPage interface.
266
* At least one role must be nested.
268
public boolean isComplete() {
269
boolean result = true;
271
if (_roleCache.isEmpty()) {
272
JOptionPane.showMessageDialog(null,
273
_resource.getString(_section, "IncompleteText"),
274
_resource.getString(_section, "IncompleteTitle"),
275
JOptionPane.ERROR_MESSAGE);
276
ModalDialogUtil.sleep();
285
* Implements the IResourceEditorPage interface.
287
public String getDisplayName() {
293
* Implements the IResourceEditorPage interface.
296
DSUtil.help("configuration-role-member-nested-help");
301
* Implements the ActionListener interface.
303
public void actionPerformed(ActionEvent e)
305
_parent.setBusyCursor(true);
306
if (e.getSource() == _addButton) {
309
else if (e.getSource() == _removeButton) {
312
_parent.setBusyCursor(false);
316
* Process a click on Add
319
ConsoleInfo info = _parent.getConsoleInfo();
320
Vector selectedRoles = null;
323
// Build the exclude list for the role picker.
325
// - the roles which are already nested
326
// - the role being edited (not useful to nest a role inside itself)
328
Vector excludeRoles = _roleCache.getRoleDNs();
329
String observedRole = _observable.getDN();
330
if (observedRole != null)
331
excludeRoles.addElement(observedRole);
334
// Popup the role picker.
335
// The picker is instructed to show all kinds of role.
339
if (_observable.isNewUser())
340
baseDn = _observable.getCreateBaseDN();
342
baseDn = RolePickerDialog.makeParentDn(_observable.getDN());
343
RolePickerDialog picker = new RolePickerDialog(_parent.getFrame(), info);
344
picker.loadWithNestableRoles(baseDn, excludeRoles.elements());
345
picker.allowMultipleSelection(true);
347
if (!picker.isCancel())
348
selectedRoles = picker.getSelectedRoles();
350
catch(LDAPException e) {
351
Debug.println("ResEditorNestedRole.actionAdd: reading roles failed with " + e);
352
// We popup a dialog to warn the user
353
DSUtil.showLDAPErrorDialog(_parent.getFrame(), e, "fetching-server-unavailable");
357
// Adds the roles in _managedRoleCache
359
if (selectedRoles != null) {
361
LDAPConnection ldc = info.getLDAPConnection();
362
Enumeration e = selectedRoles.elements();
363
while (e.hasMoreElements()) {
364
String roleDn = (String)e.nextElement();
365
DN roleDN = new DN(roleDn);
366
if ( !_roleCache.contains(roleDN) )
367
_roleCache.add(roleDn, ldc);
370
catch(LDAPException e) {
371
Debug.println("RoleEditorDialog.actionAdd: reading roles failed with " + e);
372
// We popup a dialog to warn the user
373
DSUtil.showLDAPErrorDialog(_parent.getFrame(), e,
374
"updating-directory-title");
381
* Process a click on Remove
383
void actionRemove() {
384
int roleCount = _table.getModel().getRowCount();
385
ListSelectionModel selModel = _table.getSelectionModel();
387
// 600538 Multiple elements from a vector must be deleted starting
388
// from the highest index as vector indexes change after each delete
389
for (int i = (roleCount - 1); i >= 0; i--) {
390
if (selModel.isSelectedIndex(i)) {
391
_roleCache.remove(i);
398
* Implements ListSelectionListener.
399
* Called when the user clicks in the table.
400
* We update the tooltip text and the state of _removeButton
402
public void valueChanged(ListSelectionEvent e) {
403
// Note: initialize() invokes this method with e == null
405
ListSelectionModel m = _table.getSelectionModel() ;
406
int min = m.getMinSelectionIndex() ;
407
int max = m.getMaxSelectionIndex() ;
409
// Update the tooltip text of the tab
410
if ((min == -1) || (max - min + 1 > 1) || (_table.getRowCount() <= 0)) {
411
// The selection is empty or multiple or the table is empty
412
_table.setToolTipText(null);
415
_table.setToolTipText(_roleCache.getRoleDN(min));
418
// _removeButton is disabled if the selection is empty: if we use
419
// the tab and the table gets the focus JTable.getSelectedRowCount() is 1
420
// (even if the row count is 0 !!)
421
_removeButton.setEnabled((_table.getSelectedRowCount() > 0) &&
422
(_table.getRowCount() > 0));
427
ResourceEditor _parent;
428
ResourcePageObservable _observable;
430
RoleCache _roleCache;
431
boolean _isReadOnly = false;
432
boolean _isEnabled = true;
437
JButton _removeButton;
440
static ResourceSet _resource = DSUtil._resource;
441
private static final String _section = "nestedRolePage";
444
private static final String NSROLEDN_ATTR = "nsRoleDN";
445
private static final String NSROLE_ATTR = "nsRole";
446
private static final String[] ROLE_ATTRS = { NSROLEDN_ATTR };