]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java
Introduce E4 privileged job
[lgpl/argeo-commons.git] / org.argeo.cms.e4 / src / org / argeo / cms / e4 / users / UserBatchUpdateWizard.java
1 package org.argeo.cms.e4.users;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8 import javax.transaction.SystemException;
9 import javax.transaction.UserTransaction;
10
11 import org.apache.commons.logging.Log;
12 import org.apache.commons.logging.LogFactory;
13 import org.argeo.cms.CmsException;
14 import org.argeo.cms.auth.CurrentUser;
15 import org.argeo.cms.e4.users.providers.CommonNameLP;
16 import org.argeo.cms.e4.users.providers.DomainNameLP;
17 import org.argeo.cms.e4.users.providers.MailLP;
18 import org.argeo.cms.e4.users.providers.UserNameLP;
19 import org.argeo.cms.util.UserAdminUtils;
20 import org.argeo.eclipse.ui.ColumnDefinition;
21 import org.argeo.eclipse.ui.EclipseUiUtils;
22 import org.argeo.eclipse.ui.parts.LdifUsersTable;
23 import org.argeo.naming.LdapAttrs;
24 import org.argeo.naming.LdapObjs;
25 import org.argeo.node.NodeConstants;
26 import org.eclipse.jface.dialogs.IPageChangeProvider;
27 import org.eclipse.jface.dialogs.IPageChangedListener;
28 import org.eclipse.jface.dialogs.MessageDialog;
29 import org.eclipse.jface.dialogs.PageChangedEvent;
30 import org.eclipse.jface.wizard.IWizardContainer;
31 import org.eclipse.jface.wizard.Wizard;
32 import org.eclipse.jface.wizard.WizardPage;
33 import org.eclipse.swt.SWT;
34 import org.eclipse.swt.events.ModifyEvent;
35 import org.eclipse.swt.events.ModifyListener;
36 import org.eclipse.swt.events.SelectionAdapter;
37 import org.eclipse.swt.events.SelectionEvent;
38 import org.eclipse.swt.layout.GridData;
39 import org.eclipse.swt.layout.GridLayout;
40 import org.eclipse.swt.widgets.Button;
41 import org.eclipse.swt.widgets.Combo;
42 import org.eclipse.swt.widgets.Composite;
43 import org.eclipse.swt.widgets.Text;
44 import org.osgi.framework.InvalidSyntaxException;
45 import org.osgi.service.useradmin.Role;
46 import org.osgi.service.useradmin.User;
47 import org.osgi.service.useradmin.UserAdminEvent;
48
49 /** Wizard to update users */
50 public class UserBatchUpdateWizard extends Wizard {
51
52 private final static Log log = LogFactory.getLog(UserBatchUpdateWizard.class);
53 private UserAdminWrapper userAdminWrapper;
54
55 // pages
56 private ChooseCommandWizardPage chooseCommandPage;
57 private ChooseUsersWizardPage userListPage;
58 private ValidateAndLaunchWizardPage validatePage;
59
60 // Various implemented commands keys
61 private final static String CMD_UPDATE_PASSWORD = "resetPassword";
62 private final static String CMD_UPDATE_EMAIL = "resetEmail";
63 private final static String CMD_GROUP_MEMBERSHIP = "groupMembership";
64
65 private final Map<String, String> commands = new HashMap<String, String>() {
66 private static final long serialVersionUID = 1L;
67 {
68 put("Reset password(s)", CMD_UPDATE_PASSWORD);
69 put("Reset email(s)", CMD_UPDATE_EMAIL);
70 // TODO implement role / group management
71 // put("Add/Remove from group", CMD_GROUP_MEMBERSHIP);
72 }
73 };
74
75 public UserBatchUpdateWizard(UserAdminWrapper userAdminWrapper) {
76 this.userAdminWrapper = userAdminWrapper;
77 }
78
79 @Override
80 public void addPages() {
81 chooseCommandPage = new ChooseCommandWizardPage();
82 addPage(chooseCommandPage);
83 userListPage = new ChooseUsersWizardPage();
84 addPage(userListPage);
85 validatePage = new ValidateAndLaunchWizardPage();
86 addPage(validatePage);
87 }
88
89 @Override
90 public boolean performFinish() {
91 if (!canFinish())
92 return false;
93 UserTransaction ut = userAdminWrapper.getUserTransaction();
94 try {
95 if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION
96 && !MessageDialog.openConfirm(getShell(), "Existing Transaction",
97 "A user transaction is already existing, " + "are you sure you want to proceed ?"))
98 return false;
99 } catch (SystemException e) {
100 throw new CmsException("Cannot get user transaction state " + "before user batch update", e);
101 }
102
103 // We cannot use jobs, user modifications are still meant to be done in
104 // the UIThread
105 // UpdateJob job = null;
106 // if (job != null)
107 // job.schedule();
108
109 if (CMD_UPDATE_PASSWORD.equals(chooseCommandPage.getCommand())) {
110 char[] newValue = chooseCommandPage.getPwdValue();
111 if (newValue == null)
112 throw new CmsException("Password cannot be null or an empty string");
113 ResetPassword job = new ResetPassword(userAdminWrapper, userListPage.getSelectedUsers(), newValue);
114 job.doUpdate();
115 } else if (CMD_UPDATE_EMAIL.equals(chooseCommandPage.getCommand())) {
116 String newValue = chooseCommandPage.getEmailValue();
117 if (newValue == null)
118 throw new CmsException("Password cannot be null or an empty string");
119 ResetEmail job = new ResetEmail(userAdminWrapper, userListPage.getSelectedUsers(), newValue);
120 job.doUpdate();
121 }
122 return true;
123 }
124
125 public boolean canFinish() {
126 if (this.getContainer().getCurrentPage() == validatePage)
127 return true;
128 return false;
129 }
130
131 private class ResetPassword {
132 private char[] newPwd;
133 private UserAdminWrapper userAdminWrapper;
134 private List<User> usersToUpdate;
135
136 public ResetPassword(UserAdminWrapper userAdminWrapper, List<User> usersToUpdate, char[] newPwd) {
137 this.newPwd = newPwd;
138 this.usersToUpdate = usersToUpdate;
139 this.userAdminWrapper = userAdminWrapper;
140 }
141
142 @SuppressWarnings("unchecked")
143 protected void doUpdate() {
144 userAdminWrapper.beginTransactionIfNeeded();
145 try {
146 for (User user : usersToUpdate) {
147 // the char array is emptied after being used.
148 user.getCredentials().put(null, newPwd.clone());
149 }
150 userAdminWrapper.commitOrNotifyTransactionStateChange();
151 } catch (Exception e) {
152 throw new CmsException("Cannot perform batch update on users", e);
153 } finally {
154 UserTransaction ut = userAdminWrapper.getUserTransaction();
155 try {
156 if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION)
157 ut.rollback();
158 } catch (IllegalStateException | SecurityException | SystemException e) {
159 log.error("Unable to rollback session in 'finally', " + "the system might be in a dirty state");
160 e.printStackTrace();
161 }
162 }
163 }
164 }
165
166 private class ResetEmail {
167 private String newEmail;
168 private UserAdminWrapper userAdminWrapper;
169 private List<User> usersToUpdate;
170
171 public ResetEmail(UserAdminWrapper userAdminWrapper, List<User> usersToUpdate, String newEmail) {
172 this.newEmail = newEmail;
173 this.usersToUpdate = usersToUpdate;
174 this.userAdminWrapper = userAdminWrapper;
175 }
176
177 @SuppressWarnings("unchecked")
178 protected void doUpdate() {
179 userAdminWrapper.beginTransactionIfNeeded();
180 try {
181 for (User user : usersToUpdate) {
182 // the char array is emptied after being used.
183 user.getProperties().put(LdapAttrs.mail.name(), newEmail);
184 }
185
186 userAdminWrapper.commitOrNotifyTransactionStateChange();
187 if (!usersToUpdate.isEmpty())
188 userAdminWrapper.notifyListeners(
189 new UserAdminEvent(null, UserAdminEvent.ROLE_CHANGED, usersToUpdate.get(0)));
190 } catch (Exception e) {
191 throw new CmsException("Cannot perform batch update on users", e);
192 } finally {
193 UserTransaction ut = userAdminWrapper.getUserTransaction();
194 try {
195 if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION)
196 ut.rollback();
197 } catch (IllegalStateException | SecurityException | SystemException e) {
198 log.error("Unable to rollback session in finally block, the system might be in a dirty state");
199 e.printStackTrace();
200 }
201 }
202 }
203 }
204
205 // @SuppressWarnings("unused")
206 // private class AddToGroup extends UpdateJob {
207 // private String groupID;
208 // private Session session;
209 //
210 // public AddToGroup(Session session, List<Node> nodesToUpdate,
211 // String groupID) {
212 // super(session, nodesToUpdate);
213 // this.session = session;
214 // this.groupID = groupID;
215 // }
216 //
217 // protected void doUpdate(Node node) {
218 // log.info("Add/Remove to group actions are not yet implemented");
219 // // TODO implement this
220 // // try {
221 // // throw new CmsException("Not yet implemented");
222 // // } catch (RepositoryException re) {
223 // // throw new CmsException(
224 // // "Unable to update boolean value for node " + node, re);
225 // // }
226 // }
227 // }
228
229 // /**
230 // * Base privileged job that will be run asynchronously to perform the
231 // batch
232 // * update
233 // */
234 // private abstract class UpdateJob extends PrivilegedJob {
235 //
236 // private final UserAdminWrapper userAdminWrapper;
237 // private final List<User> usersToUpdate;
238 //
239 // protected abstract void doUpdate(User user);
240 //
241 // public UpdateJob(UserAdminWrapper userAdminWrapper,
242 // List<User> usersToUpdate) {
243 // super("Perform update");
244 // this.usersToUpdate = usersToUpdate;
245 // this.userAdminWrapper = userAdminWrapper;
246 // }
247 //
248 // @Override
249 // protected IStatus doRun(IProgressMonitor progressMonitor) {
250 // try {
251 // JcrMonitor monitor = new EclipseJcrMonitor(progressMonitor);
252 // int total = usersToUpdate.size();
253 // monitor.beginTask("Performing change", total);
254 // userAdminWrapper.beginTransactionIfNeeded();
255 // for (User user : usersToUpdate) {
256 // doUpdate(user);
257 // monitor.worked(1);
258 // }
259 // userAdminWrapper.getUserTransaction().commit();
260 // } catch (Exception e) {
261 // throw new CmsException(
262 // "Cannot perform batch update on users", e);
263 // } finally {
264 // UserTransaction ut = userAdminWrapper.getUserTransaction();
265 // try {
266 // if (ut.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION)
267 // ut.rollback();
268 // } catch (IllegalStateException | SecurityException
269 // | SystemException e) {
270 // log.error("Unable to rollback session in 'finally', "
271 // + "the system might be in a dirty state");
272 // e.printStackTrace();
273 // }
274 // }
275 // return Status.OK_STATUS;
276 // }
277 // }
278
279 // PAGES
280 /**
281 * Displays a combo box that enables user to choose which action to perform
282 */
283 private class ChooseCommandWizardPage extends WizardPage {
284 private static final long serialVersionUID = -8069434295293996633L;
285 private Combo chooseCommandCmb;
286 private Button trueChk;
287 private Text valueTxt;
288 private Text pwdTxt;
289 private Text pwd2Txt;
290
291 public ChooseCommandWizardPage() {
292 super("Choose a command to run.");
293 setTitle("Choose a command to run.");
294 }
295
296 @Override
297 public void createControl(Composite parent) {
298 GridLayout gl = new GridLayout();
299 Composite container = new Composite(parent, SWT.NO_FOCUS);
300 container.setLayout(gl);
301
302 chooseCommandCmb = new Combo(container, SWT.READ_ONLY);
303 chooseCommandCmb.setLayoutData(EclipseUiUtils.fillWidth());
304 String[] values = commands.keySet().toArray(new String[0]);
305 chooseCommandCmb.setItems(values);
306
307 final Composite bottomPart = new Composite(container, SWT.NO_FOCUS);
308 bottomPart.setLayoutData(EclipseUiUtils.fillAll());
309 bottomPart.setLayout(EclipseUiUtils.noSpaceGridLayout());
310
311 chooseCommandCmb.addSelectionListener(new SelectionAdapter() {
312 private static final long serialVersionUID = 1L;
313
314 @Override
315 public void widgetSelected(SelectionEvent e) {
316 if (getCommand().equals(CMD_UPDATE_PASSWORD))
317 populatePasswordCmp(bottomPart);
318 else if (getCommand().equals(CMD_UPDATE_EMAIL))
319 populateEmailCmp(bottomPart);
320 else if (getCommand().equals(CMD_GROUP_MEMBERSHIP))
321 populateGroupCmp(bottomPart);
322 else
323 populateBooleanFlagCmp(bottomPart);
324 checkPageComplete();
325 bottomPart.layout(true, true);
326 }
327 });
328 setControl(container);
329 }
330
331 private void populateBooleanFlagCmp(Composite parent) {
332 EclipseUiUtils.clear(parent);
333 trueChk = new Button(parent, SWT.CHECK);
334 trueChk.setText("Do it. (It will to the contrary if unchecked)");
335 trueChk.setSelection(true);
336 trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
337 }
338
339 private void populatePasswordCmp(Composite parent) {
340 EclipseUiUtils.clear(parent);
341 Composite body = new Composite(parent, SWT.NO_FOCUS);
342
343 ModifyListener ml = new ModifyListener() {
344 private static final long serialVersionUID = -1558726363536729634L;
345
346 @Override
347 public void modifyText(ModifyEvent event) {
348 checkPageComplete();
349 }
350 };
351
352 body.setLayout(new GridLayout(2, false));
353 body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
354 pwdTxt = EclipseUiUtils.createGridLP(body, "New password", ml);
355 pwd2Txt = EclipseUiUtils.createGridLP(body, "Repeat password", ml);
356 }
357
358 private void populateEmailCmp(Composite parent) {
359 EclipseUiUtils.clear(parent);
360 Composite body = new Composite(parent, SWT.NO_FOCUS);
361
362 ModifyListener ml = new ModifyListener() {
363 private static final long serialVersionUID = 2147704227294268317L;
364
365 @Override
366 public void modifyText(ModifyEvent event) {
367 checkPageComplete();
368 }
369 };
370
371 body.setLayout(new GridLayout(2, false));
372 body.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
373 valueTxt = EclipseUiUtils.createGridLT(body, "New e-mail", ml);
374 }
375
376 private void checkPageComplete() {
377 String errorMsg = null;
378 if (chooseCommandCmb.getSelectionIndex() < 0)
379 errorMsg = "Please select an action";
380 else if (CMD_UPDATE_EMAIL.equals(getCommand())) {
381 if (!valueTxt.getText().matches(UiAdminUtils.EMAIL_PATTERN))
382 errorMsg = "Not a valid e-mail address";
383 } else if (CMD_UPDATE_PASSWORD.equals(getCommand())) {
384 if (EclipseUiUtils.isEmpty(pwdTxt.getText()) || pwdTxt.getText().length() < 4)
385 errorMsg = "Please enter a password that is at least 4 character long";
386 else if (!pwdTxt.getText().equals(pwd2Txt.getText()))
387 errorMsg = "Passwords are different";
388 }
389 if (EclipseUiUtils.notEmpty(errorMsg)) {
390 setMessage(errorMsg, WizardPage.ERROR);
391 setPageComplete(false);
392 } else {
393 setMessage("Page complete, you can proceed to user choice", WizardPage.INFORMATION);
394 setPageComplete(true);
395 }
396
397 getContainer().updateButtons();
398 }
399
400 private void populateGroupCmp(Composite parent) {
401 EclipseUiUtils.clear(parent);
402 trueChk = new Button(parent, SWT.CHECK);
403 trueChk.setText("Add to group. (It will remove user(s) from the " + "corresponding group if unchecked)");
404 trueChk.setSelection(true);
405 trueChk.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false));
406 }
407
408 protected String getCommand() {
409 return commands.get(chooseCommandCmb.getItem(chooseCommandCmb.getSelectionIndex()));
410 }
411
412 protected String getCommandLbl() {
413 return chooseCommandCmb.getItem(chooseCommandCmb.getSelectionIndex());
414 }
415
416 @SuppressWarnings("unused")
417 protected boolean getBoleanValue() {
418 // FIXME this is not consistent and will lead to errors.
419 if ("argeo:enabled".equals(getCommand()))
420 return trueChk.getSelection();
421 else
422 return !trueChk.getSelection();
423 }
424
425 @SuppressWarnings("unused")
426 protected String getStringValue() {
427 String value = null;
428 if (valueTxt != null) {
429 value = valueTxt.getText();
430 if ("".equals(value.trim()))
431 value = null;
432 }
433 return value;
434 }
435
436 protected char[] getPwdValue() {
437 // We do not directly reset the password text fields: There is no
438 // need to over secure this process: setting a pwd to multi users
439 // at the same time is anyhow a bad practice and should be used only
440 // in test environment or for temporary access
441 if (pwdTxt == null || pwdTxt.isDisposed())
442 return null;
443 else
444 return pwdTxt.getText().toCharArray();
445 }
446
447 protected String getEmailValue() {
448 // We do not directly reset the password text fields: There is no
449 // need to over secure this process: setting a pwd to multi users
450 // at the same time is anyhow a bad practice and should be used only
451 // in test environment or for temporary access
452 if (valueTxt == null || valueTxt.isDisposed())
453 return null;
454 else
455 return valueTxt.getText();
456 }
457 }
458
459 /**
460 * Displays a list of users with a check box to be able to choose some of
461 * them
462 */
463 private class ChooseUsersWizardPage extends WizardPage implements IPageChangedListener {
464 private static final long serialVersionUID = 7651807402211214274L;
465 private ChooseUserTableViewer userTableCmp;
466
467 public ChooseUsersWizardPage() {
468 super("Choose Users");
469 setTitle("Select users who will be impacted");
470 }
471
472 @Override
473 public void createControl(Composite parent) {
474 Composite pageCmp = new Composite(parent, SWT.NONE);
475 pageCmp.setLayout(EclipseUiUtils.noSpaceGridLayout());
476
477 // Define the displayed columns
478 List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
479 columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", 150));
480 columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150));
481 columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200));
482
483 // Only show technical DN to admin
484 if (CurrentUser.isInRole(NodeConstants.ROLE_ADMIN))
485 columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300));
486
487 userTableCmp = new ChooseUserTableViewer(pageCmp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
488 userTableCmp.setLayoutData(EclipseUiUtils.fillAll());
489 userTableCmp.setColumnDefinitions(columnDefs);
490 userTableCmp.populate(true, true);
491 userTableCmp.refresh();
492
493 setControl(pageCmp);
494
495 // Add listener to update message when shown
496 final IWizardContainer wContainer = this.getContainer();
497 if (wContainer instanceof IPageChangeProvider) {
498 ((IPageChangeProvider) wContainer).addPageChangedListener(this);
499 }
500
501 }
502
503 @Override
504 public void pageChanged(PageChangedEvent event) {
505 if (event.getSelectedPage() == this) {
506 String msg = "Chosen batch action: " + chooseCommandPage.getCommandLbl();
507 ((WizardPage) event.getSelectedPage()).setMessage(msg);
508 }
509 }
510
511 protected List<User> getSelectedUsers() {
512 return userTableCmp.getSelectedUsers();
513 }
514
515 private class ChooseUserTableViewer extends LdifUsersTable {
516 private static final long serialVersionUID = 5080437561015853124L;
517 private final String[] knownProps = { LdapAttrs.uid.name(), LdapAttrs.DN, LdapAttrs.cn.name(),
518 LdapAttrs.givenName.name(), LdapAttrs.sn.name(), LdapAttrs.mail.name() };
519
520 public ChooseUserTableViewer(Composite parent, int style) {
521 super(parent, style);
522 }
523
524 @Override
525 protected List<User> listFilteredElements(String filter) {
526 Role[] roles;
527
528 try {
529 StringBuilder builder = new StringBuilder();
530
531 StringBuilder tmpBuilder = new StringBuilder();
532 if (EclipseUiUtils.notEmpty(filter))
533 for (String prop : knownProps) {
534 tmpBuilder.append("(");
535 tmpBuilder.append(prop);
536 tmpBuilder.append("=*");
537 tmpBuilder.append(filter);
538 tmpBuilder.append("*)");
539 }
540 if (tmpBuilder.length() > 1) {
541 builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=")
542 .append(LdapObjs.inetOrgPerson.name()).append(")(|");
543 builder.append(tmpBuilder.toString());
544 builder.append("))");
545 } else
546 builder.append("(").append(LdapAttrs.objectClass.name()).append("=")
547 .append(LdapObjs.inetOrgPerson.name()).append(")");
548 roles = userAdminWrapper.getUserAdmin().getRoles(builder.toString());
549 } catch (InvalidSyntaxException e) {
550 throw new CmsException("Unable to get roles with filter: " + filter, e);
551 }
552 List<User> users = new ArrayList<User>();
553 for (Role role : roles)
554 // Prevent current logged in user to perform batch on
555 // himself
556 if (!UserAdminUtils.isCurrentUser((User) role))
557 users.add((User) role);
558 return users;
559 }
560 }
561 }
562
563 /** Summary of input data before launching the process */
564 private class ValidateAndLaunchWizardPage extends WizardPage implements IPageChangedListener {
565 private static final long serialVersionUID = 7098918351451743853L;
566 private ChosenUsersTableViewer userTableCmp;
567
568 public ValidateAndLaunchWizardPage() {
569 super("Validate and launch");
570 setTitle("Validate and launch");
571 }
572
573 @Override
574 public void createControl(Composite parent) {
575 Composite pageCmp = new Composite(parent, SWT.NO_FOCUS);
576 pageCmp.setLayout(EclipseUiUtils.noSpaceGridLayout());
577
578 List<ColumnDefinition> columnDefs = new ArrayList<ColumnDefinition>();
579 columnDefs.add(new ColumnDefinition(new CommonNameLP(), "Common Name", 150));
580 columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150));
581 columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200));
582 // Only show technical DN to admin
583 if (CurrentUser.isInRole(NodeConstants.ROLE_ADMIN))
584 columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300));
585 userTableCmp = new ChosenUsersTableViewer(pageCmp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
586 userTableCmp.setLayoutData(EclipseUiUtils.fillAll());
587 userTableCmp.setColumnDefinitions(columnDefs);
588 userTableCmp.populate(false, false);
589 userTableCmp.refresh();
590 setControl(pageCmp);
591 // Add listener to update message when shown
592 final IWizardContainer wContainer = this.getContainer();
593 if (wContainer instanceof IPageChangeProvider) {
594 ((IPageChangeProvider) wContainer).addPageChangedListener(this);
595 }
596 }
597
598 @Override
599 public void pageChanged(PageChangedEvent event) {
600 if (event.getSelectedPage() == this) {
601 @SuppressWarnings({ "unchecked", "rawtypes" })
602 Object[] values = ((ArrayList) userListPage.getSelectedUsers())
603 .toArray(new Object[userListPage.getSelectedUsers().size()]);
604 userTableCmp.getTableViewer().setInput(values);
605 String msg = "Following batch action: [" + chooseCommandPage.getCommandLbl()
606 + "] will be perfomed on the users listed below.\n";
607 // + "Are you sure you want to proceed?";
608 setMessage(msg);
609 }
610 }
611
612 private class ChosenUsersTableViewer extends LdifUsersTable {
613 private static final long serialVersionUID = 7814764735794270541L;
614
615 public ChosenUsersTableViewer(Composite parent, int style) {
616 super(parent, style);
617 }
618
619 @Override
620 protected List<User> listFilteredElements(String filter) {
621 return userListPage.getSelectedUsers();
622 }
623 }
624 }
625 }