001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2009-2010 Sun Microsystems, Inc. 025 * Portions Copyright 2014-2015 ForgeRock AS 026 */ 027 028package org.opends.guitools.controlpanel.ui; 029 030import static org.forgerock.util.Utils.*; 031import static org.opends.messages.AdminToolMessages.*; 032import static org.opends.server.util.CollectionUtils.*; 033import static org.opends.server.util.StaticUtils.*; 034 035import java.awt.Component; 036import java.awt.GridBagConstraints; 037import java.awt.GridBagLayout; 038import java.awt.event.ActionEvent; 039import java.awt.event.ActionListener; 040import java.awt.event.KeyEvent; 041import java.util.ArrayList; 042import java.util.HashMap; 043import java.util.HashSet; 044import java.util.LinkedHashSet; 045import java.util.List; 046import java.util.Map; 047import java.util.Random; 048import java.util.Set; 049 050import javax.swing.Box; 051import javax.swing.JButton; 052import javax.swing.JLabel; 053import javax.swing.JMenu; 054import javax.swing.JMenuBar; 055import javax.swing.JMenuItem; 056import javax.swing.JPanel; 057import javax.swing.JScrollPane; 058import javax.swing.JTable; 059import javax.swing.JTextArea; 060import javax.swing.ListSelectionModel; 061import javax.swing.SwingUtilities; 062import javax.swing.event.ListSelectionEvent; 063import javax.swing.event.ListSelectionListener; 064 065import org.forgerock.i18n.LocalizableMessage; 066import org.forgerock.i18n.slf4j.LocalizedLogger; 067import org.forgerock.opendj.ldap.ByteString; 068import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; 069import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; 070import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; 071import org.opends.guitools.controlpanel.datamodel.TaskTableModel; 072import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; 073import org.opends.guitools.controlpanel.task.CancelTaskTask; 074import org.opends.guitools.controlpanel.task.Task; 075import org.opends.guitools.controlpanel.ui.renderer.TaskCellRenderer; 076import org.opends.guitools.controlpanel.util.ConfigFromFile; 077import org.opends.guitools.controlpanel.util.Utilities; 078import org.opends.server.core.DirectoryServer; 079import org.opends.server.tools.tasks.TaskEntry; 080import org.opends.server.types.Attribute; 081import org.opends.server.types.AttributeBuilder; 082import org.opends.server.types.AttributeType; 083import org.opends.server.types.DN; 084import org.opends.server.types.Entry; 085import org.opends.server.types.ObjectClass; 086import org.opends.server.types.OpenDsException; 087 088/** 089 * The panel displaying the list of scheduled tasks. 090 * 091 */ 092public class ManageTasksPanel extends StatusGenericPanel 093{ 094 private static final long serialVersionUID = -8034784684412532193L; 095 096 private JLabel lNoTasksFound; 097 098 /** 099 * Remove task button. 100 */ 101 private JButton cancelTask; 102 /** 103 * The scroll that contains the list of tasks (actually is a table). 104 */ 105 private JScrollPane tableScroll; 106 /** 107 * The table of tasks. 108 */ 109 private JTable taskTable; 110 111 /** 112 * The model of the table. 113 */ 114 private TaskTableModel tableModel; 115 116 private ManageTasksMenuBar menuBar; 117 118 private MonitoringAttributesViewPanel<LocalizableMessage> operationViewPanel; 119 private GenericDialog operationViewDlg; 120 121 private JPanel detailsPanel; 122 private JLabel noDetailsLabel; 123 /** The panel containing all the labels and values of the details. */ 124 private JPanel detailsSubpanel; 125 private JLabel logsLabel; 126 private JScrollPane logsScroll; 127 private JTextArea logs; 128 private JLabel noLogsLabel; 129 130 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 131 132 /** Default constructor. */ 133 public ManageTasksPanel() 134 { 135 super(); 136 createLayout(); 137 } 138 139 /** {@inheritDoc} */ 140 public LocalizableMessage getTitle() 141 { 142 return INFO_CTRL_PANEL_TASK_TO_SCHEDULE_LIST_TITLE.get(); 143 } 144 145 /** {@inheritDoc} */ 146 public boolean requiresScroll() 147 { 148 return false; 149 } 150 151 /** {@inheritDoc} */ 152 public GenericDialog.ButtonType getButtonType() 153 { 154 return GenericDialog.ButtonType.CLOSE; 155 } 156 157 /** {@inheritDoc} */ 158 public void okClicked() 159 { 160 // Nothing to do, it only contains a close button. 161 } 162 163 /** {@inheritDoc} */ 164 @Override 165 public JMenuBar getMenuBar() 166 { 167 if (menuBar == null) 168 { 169 menuBar = new ManageTasksMenuBar(getInfo()); 170 } 171 return menuBar; 172 } 173 174 /** {@inheritDoc} */ 175 public Component getPreferredFocusComponent() 176 { 177 return taskTable; 178 } 179 180 /** 181 * Returns the selected cancelable tasks in the list. 182 * @param onlyCancelable add only the cancelable tasks. 183 * @return the selected cancelable tasks in the list. 184 */ 185 private List<TaskEntry> getSelectedTasks(boolean onlyCancelable) 186 { 187 ArrayList<TaskEntry> tasks = new ArrayList<>(); 188 int[] rows = taskTable.getSelectedRows(); 189 for (int row : rows) 190 { 191 if (row != -1) 192 { 193 TaskEntry task = tableModel.get(row); 194 if (!onlyCancelable || task.isCancelable()) 195 { 196 tasks.add(task); 197 } 198 } 199 } 200 return tasks; 201 } 202 203 /** 204 * Creates the components and lays them in the panel. 205 * @param gbc the grid bag constraints to be used. 206 */ 207 private void createLayout() 208 { 209 GridBagConstraints gbc = new GridBagConstraints(); 210 gbc.anchor = GridBagConstraints.WEST; 211 gbc.gridx = 0; 212 gbc.gridy = 0; 213 gbc.gridwidth = 2; 214 addErrorPane(gbc); 215 216 gbc.weightx = 0.0; 217 gbc.gridy ++; 218 gbc.anchor = GridBagConstraints.WEST; 219 gbc.weightx = 0.0; 220 gbc.fill = GridBagConstraints.NONE; 221 gbc.gridwidth = 2; 222 gbc.insets.left = 0; 223 gbc.gridx = 0; 224 gbc.gridy = 0; 225 lNoTasksFound = Utilities.createDefaultLabel( 226 INFO_CTRL_PANEL_NO_TASKS_FOUND.get()); 227 gbc.gridy ++; 228 gbc.anchor = GridBagConstraints.CENTER; 229 gbc.gridheight = 2; 230 add(lNoTasksFound, gbc); 231 lNoTasksFound.setVisible(false); 232 233 gbc.gridwidth = 1; 234 gbc.weightx = 1.0; 235 gbc.weighty = 1.0; 236 gbc.fill = GridBagConstraints.BOTH; 237 gbc.insets.top = 10; 238 gbc.anchor = GridBagConstraints.NORTHWEST; 239 // Done to provide a good size to the table. 240 tableModel = new TaskTableModel() 241 { 242 private static final long serialVersionUID = 55555512319230987L; 243 244 /** 245 * Updates the table model contents and sorts its contents depending on 246 * the sort options set by the user. 247 */ 248 public void forceResort() 249 { 250 Set<String> selectedIds = getSelectedIds(); 251 super.forceResort(); 252 setSelectedIds(selectedIds); 253 } 254 }; 255 tableModel.setData(createDummyTaskList()); 256 taskTable = 257 Utilities.createSortableTable(tableModel, new TaskCellRenderer()); 258 taskTable.getSelectionModel().setSelectionMode( 259 ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 260 tableScroll = Utilities.createScrollPane(taskTable); 261 add(tableScroll, gbc); 262 updateTableSizes(); 263 int height = taskTable.getPreferredScrollableViewportSize().height; 264 add(Box.createVerticalStrut(height), gbc); 265 266 gbc.gridx = 1; 267 gbc.gridheight = 1; 268 gbc.anchor = GridBagConstraints.EAST; 269 gbc.fill = GridBagConstraints.NONE; 270 gbc.weightx = 0.0; 271 gbc.weighty = 0.0; 272 cancelTask = Utilities.createButton( 273 INFO_CTRL_PANEL_CANCEL_TASK_BUTTON_LABEL.get()); 274 cancelTask.setOpaque(false); 275 gbc.insets.left = 10; 276 add(cancelTask, gbc); 277 278 gbc.gridy ++; 279 gbc.weighty = 1.0; 280 gbc.fill = GridBagConstraints.VERTICAL; 281 add(Box.createVerticalGlue(), gbc); 282 cancelTask.addActionListener(new ActionListener() 283 { 284 /** {@inheritDoc} */ 285 public void actionPerformed(ActionEvent ev) 286 { 287 cancelTaskClicked(); 288 } 289 }); 290 291 gbc.gridy ++; 292 gbc.gridx = 0; 293 gbc.gridwidth = 2; 294 gbc.weightx = 0.0; 295 gbc.weighty = 0.0; 296 gbc.fill = GridBagConstraints.HORIZONTAL; 297 gbc.anchor = GridBagConstraints.NORTHWEST; 298 gbc.insets.top = 15; 299 gbc.insets.left = 0; 300 logsLabel = Utilities.createDefaultLabel( 301 INFO_CTRL_PANEL_TASK_LOG_LABEL.get()); 302 logsLabel.setFont(ColorAndFontConstants.titleFont); 303 add(logsLabel, gbc); 304 305 logs = Utilities.createNonEditableTextArea(LocalizableMessage.EMPTY, 5, 50); 306 logs.setFont(ColorAndFontConstants.defaultFont); 307 gbc.fill = GridBagConstraints.BOTH; 308 gbc.weightx = 1.0; 309 gbc.weighty = 0.7; 310 gbc.gridy ++; 311 gbc.insets.top = 5; 312 logsScroll = Utilities.createScrollPane(logs); 313 add(logsScroll, gbc); 314 height = logs.getPreferredSize().height; 315 add(Box.createVerticalStrut(height), gbc); 316 logsScroll.setVisible(false); 317 318 gbc.anchor = GridBagConstraints.CENTER; 319 gbc.fill = GridBagConstraints.NONE; 320 gbc.weightx = 1.0; 321 gbc.weighty = 1.0; 322 noLogsLabel = 323 Utilities.createDefaultLabel(INFO_CTRL_PANEL_NO_TASK_SELECTED.get()); 324 add(noLogsLabel, gbc); 325 326 gbc.fill = GridBagConstraints.BOTH; 327 gbc.weightx = 1.0; 328 gbc.weighty = 0.8; 329 gbc.gridy ++; 330 gbc.insets.left = 0; 331 gbc.insets.top = 15; 332 createDetailsPanel(); 333 add(detailsPanel, gbc); 334 335 ListSelectionListener listener = new ListSelectionListener() 336 { 337 /** {@inheritDoc} */ 338 public void valueChanged(ListSelectionEvent ev) 339 { 340 tableSelected(); 341 } 342 }; 343 taskTable.getSelectionModel().addListSelectionListener(listener); 344 listener.valueChanged(null); 345 } 346 347 /** 348 * Creates the details panel. 349 * 350 */ 351 private void createDetailsPanel() 352 { 353 detailsPanel = new JPanel(new GridBagLayout()); 354 detailsPanel.setOpaque(false); 355 356 GridBagConstraints gbc = new GridBagConstraints(); 357 gbc.gridx = 1; 358 gbc.gridy = 1; 359 gbc.anchor = GridBagConstraints.NORTHWEST; 360 JLabel label = Utilities.createDefaultLabel( 361 INFO_CTRL_PANEL_TASK_SPECIFIC_DETAILS.get()); 362 label.setFont(ColorAndFontConstants.titleFont); 363 detailsPanel.add(label, gbc); 364 gbc.gridy ++; 365 gbc.anchor = GridBagConstraints.CENTER; 366 gbc.fill = GridBagConstraints.NONE; 367 gbc.weightx = 1.0; 368 gbc.weighty = 1.0; 369 noDetailsLabel = 370 Utilities.createDefaultLabel(INFO_CTRL_PANEL_NO_TASK_SELECTED.get()); 371 gbc.gridwidth = 2; 372 detailsPanel.add(noDetailsLabel, gbc); 373 374 detailsSubpanel = new JPanel(new GridBagLayout()); 375 detailsSubpanel.setOpaque(false); 376 gbc.anchor = GridBagConstraints.NORTHWEST; 377 gbc.fill = GridBagConstraints.BOTH; 378 detailsPanel.add(Utilities.createBorderLessScrollBar(detailsSubpanel), gbc); 379 380 detailsPanel.add( 381 Box.createVerticalStrut(logs.getPreferredSize().height), gbc); 382 } 383 384 /** 385 * Method called when the table is selected. 386 * 387 */ 388 private void tableSelected() 389 { 390 List<TaskEntry> tasks = getSelectedTasks(true); 391 cancelTask.setEnabled(!tasks.isEmpty()); 392 393 detailsSubpanel.removeAll(); 394 395 tasks = getSelectedTasks(false); 396 397 boolean displayContents = false; 398 if (tasks.isEmpty()) 399 { 400 noDetailsLabel.setText(INFO_CTRL_PANEL_NO_TASK_SELECTED.get().toString()); 401 logsScroll.setVisible(false); 402 noLogsLabel.setText(INFO_CTRL_PANEL_NO_TASK_SELECTED.get().toString()); 403 noLogsLabel.setVisible(true); 404 } 405 else if (tasks.size() > 1) 406 { 407 noDetailsLabel.setText( 408 INFO_CTRL_PANEL_MULTIPLE_TASKS_SELECTED.get().toString()); 409 logsScroll.setVisible(false); 410 noLogsLabel.setText( 411 INFO_CTRL_PANEL_MULTIPLE_TASKS_SELECTED.get().toString()); 412 noLogsLabel.setVisible(true); 413 } 414 else 415 { 416 TaskEntry taskEntry = tasks.iterator().next(); 417 Map<LocalizableMessage,List<String>> taskSpecificAttrs = 418 taskEntry.getTaskSpecificAttributeValuePairs(); 419 List<LocalizableMessage> lastLogMessages = taskEntry.getLogMessages(); 420 if (!lastLogMessages.isEmpty()) 421 { 422 StringBuilder sb = new StringBuilder(); 423 for (LocalizableMessage msg : lastLogMessages) 424 { 425 if (sb.length() != 0) 426 { 427 sb.append("\n"); 428 } 429 sb.append(msg); 430 } 431 logs.setText(sb.toString()); 432 } 433 else 434 { 435 logs.setText(""); 436 } 437 logsScroll.setVisible(true); 438 noLogsLabel.setVisible(false); 439 440 if (taskSpecificAttrs.isEmpty()) 441 { 442 noDetailsLabel.setText( 443 INFO_CTRL_PANEL_NO_TASK_SPECIFIC_DETAILS.get().toString()); 444 } 445 else 446 { 447 displayContents = true; 448 GridBagConstraints gbc = new GridBagConstraints(); 449 gbc.gridy = 0; 450 gbc.fill = GridBagConstraints.NONE; 451 gbc.anchor = GridBagConstraints.NORTHWEST; 452 gbc.insets.top = 10; 453 for (LocalizableMessage label : taskSpecificAttrs.keySet()) 454 { 455 List<String> values = taskSpecificAttrs.get(label); 456 gbc.gridx = 0; 457 gbc.insets.left = 10; 458 gbc.insets.right = 0; 459 detailsSubpanel.add(Utilities.createPrimaryLabel( 460 INFO_CTRL_PANEL_OPERATION_NAME_AS_LABEL.get(label)), 461 gbc); 462 463 gbc.gridx = 1; 464 gbc.insets.right = 10; 465 466 String s = joinAsString("\n", values); 467 detailsSubpanel.add( 468 Utilities.makeHtmlPane(s, ColorAndFontConstants.defaultFont), 469 gbc); 470 471 gbc.gridy ++; 472 } 473 gbc.gridx = 0; 474 gbc.gridwidth = 2; 475 gbc.weightx = 1.0; 476 gbc.weighty = 1.0; 477 gbc.fill = GridBagConstraints.BOTH; 478 detailsSubpanel.add(Box.createGlue(), gbc); 479 } 480 } 481 noDetailsLabel.setVisible(!displayContents); 482 revalidate(); 483 repaint(); 484 } 485 486 /** 487 * Creates a list with task descriptors. This is done simply to have a good 488 * initial size for the table. 489 * @return a list with bogus task descriptors. 490 */ 491 private Set<TaskEntry> createRandomTasksList() 492 { 493 Set<TaskEntry> list = new HashSet<>(); 494 Random r = new Random(); 495 int numberTasks = r.nextInt(10); 496 for (int i= 0; i<numberTasks; i++) 497 { 498 CustomSearchResult csr = 499 new CustomSearchResult("cn=mytask"+i+",cn=tasks"); 500 String p = "ds-task-"; 501 String[] attrNames = 502 { 503 p + "id", 504 p + "class-name", 505 p + "state", 506 p + "scheduled-start-time", 507 p + "actual-start-time", 508 p + "completion-time", 509 p + "dependency-id", 510 p + "failed-dependency-action", 511 p + "log-message", 512 p + "notify-on-error", 513 p + "notify-on-completion", 514 p + "ds-recurring-task-schedule" 515 }; 516 String[] values = 517 { 518 "ID", 519 "TheClassName", 520 "TheState", 521 "Schedule Start Time", 522 "Actual Start Time", 523 "Completion Time", 524 "Dependency ID", 525 "Failed Dependency Action", 526 "Log LocalizableMessage. Should be pretty long"+ 527 "Log LocalizableMessage. Should be pretty long"+ 528 "Log LocalizableMessage. Should be pretty long"+ 529 "Log LocalizableMessage. Should be pretty long"+ 530 "Log LocalizableMessage. Should be pretty long", 531 "Notify On Error", 532 "Notify On Completion", 533 "Recurring Task Schedule" 534 }; 535 for (int j=0; j < attrNames.length; j++) 536 { 537 Object o = values[j] + r.nextInt(); 538 csr.set(attrNames[j], newArrayList(o)); 539 } 540 try 541 { 542 Entry entry = getEntry(csr); 543 TaskEntry task = new TaskEntry(entry); 544 list.add(task); 545 } 546 catch (Throwable t) 547 { 548 logger.error(LocalizableMessage.raw("Error getting entry '"+csr.getDN()+"': "+t, t)); 549 } 550 } 551 return list; 552 } 553 554 /** 555 * Creates a list with task descriptors. This is done simply to have a good 556 * initial size for the table. 557 * @return a list with bogus task descriptors. 558 */ 559 private Set<TaskEntry> createDummyTaskList() 560 { 561 Set<TaskEntry> list = new HashSet<>(); 562 for (int i= 0; i<10; i++) 563 { 564 CustomSearchResult csr = 565 new CustomSearchResult("cn=mytask"+i+",cn=tasks"); 566 String p = "ds-task-"; 567 String[] attrNames = 568 { 569 p + "id", 570 p + "class-name", 571 p + "state", 572 p + "scheduled-start-time", 573 p + "actual-start-time", 574 p + "completion-time", 575 p + "dependency-id", 576 p + "failed-dependency-action", 577 p + "log-message", 578 p + "notify-on-error", 579 p + "notify-on-completion", 580 p + "ds-recurring-task-schedule" 581 }; 582 String[] values = 583 { 584 "A very 29-backup - Sun Mar 29 00:00:00 MET 2009", 585 "A long task type", 586 "A very long task status", 587 "Schedule Start Time", 588 "Actual Start Time", 589 "Completion Time", 590 "Dependency ID", 591 "Failed Dependency Action", 592 "Log LocalizableMessage. Should be pretty long\n"+ 593 "Log LocalizableMessage. Should be pretty long\n"+ 594 "Log LocalizableMessage. Should be pretty long\n"+ 595 "Log LocalizableMessage. Should be pretty long\n"+ 596 "Log LocalizableMessage. Should be pretty long\n", 597 "Notify On Error", 598 "Notify On Completion", 599 "Recurring Task Schedule" 600 }; 601 for (int j=0; j < attrNames.length; j++) 602 { 603 Object o = values[j]; 604 csr.set(attrNames[j], newArrayList(o)); 605 } 606 try 607 { 608 Entry entry = getEntry(csr); 609 TaskEntry task = new TaskEntry(entry); 610 list.add(task); 611 } 612 catch (Throwable t) 613 { 614 logger.error(LocalizableMessage.raw("Error getting entry '"+csr.getDN()+"': "+t, t)); 615 } 616 } 617 return list; 618 } 619 620 private void cancelTaskClicked() 621 { 622 ArrayList<LocalizableMessage> errors = new ArrayList<>(); 623 ProgressDialog dlg = new ProgressDialog( 624 Utilities.createFrame(), 625 Utilities.getParentDialog(this), 626 INFO_CTRL_PANEL_CANCEL_TASK_TITLE.get(), getInfo()); 627 List<TaskEntry> tasks = getSelectedTasks(true); 628 CancelTaskTask newTask = new CancelTaskTask(getInfo(), dlg, tasks); 629 for (Task task : getInfo().getTasks()) 630 { 631 task.canLaunch(newTask, errors); 632 } 633 if (errors.isEmpty()) 634 { 635 boolean confirmed = displayConfirmationDialog( 636 INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(), 637 INFO_CTRL_PANEL_CANCEL_TASK_MSG.get()); 638 if (confirmed) 639 { 640 launchOperation(newTask, 641 INFO_CTRL_PANEL_CANCELING_TASK_SUMMARY.get(), 642 INFO_CTRL_PANEL_CANCELING_TASK_COMPLETE.get(), 643 INFO_CTRL_PANEL_CANCELING_TASK_SUCCESSFUL.get(), 644 ERR_CTRL_PANEL_CANCELING_TASK_ERROR_SUMMARY.get(), 645 ERR_CTRL_PANEL_CANCELING_TASK_ERROR_DETAILS.get(), 646 null, 647 dlg); 648 dlg.setVisible(true); 649 } 650 } 651 } 652 653 654 655 /** 656 * Gets the Entry object equivalent to the provided CustomSearchResult. 657 * The method assumes that the schema in DirectoryServer has been initialized. 658 * @param csr the search result. 659 * @return the Entry object equivalent to the provided CustomSearchResult. 660 * @throws OpenDsException if there is an error parsing the DN or retrieving 661 * the attributes definition and objectclasses in the schema of the server. 662 * TODO: move somewhere better. 663 */ 664 public static Entry getEntry(CustomSearchResult csr) throws OpenDsException 665 { 666 DN dn = DN.valueOf(csr.getDN()); 667 Map<ObjectClass,String> objectClasses = new HashMap<>(); 668 Map<AttributeType,List<Attribute>> userAttributes = new HashMap<>(); 669 Map<AttributeType,List<Attribute>> operationalAttributes = new HashMap<>(); 670 671 for (String wholeName : csr.getAttributeNames()) 672 { 673 final Attribute attribute = parseAttrDescription(wholeName); 674 final String attrName = attribute.getName(); 675 final String lowerName = toLowerCase(attrName); 676 677 // See if this is an objectclass or an attribute. Then get the 678 // corresponding definition and add the value to the appropriate hash. 679 if (lowerName.equals("objectclass")) 680 { 681 for (Object value : csr.getAttributeValues(attrName)) 682 { 683 String ocName = value.toString().trim(); 684 String lowerOCName = toLowerCase(ocName); 685 686 ObjectClass objectClass = 687 DirectoryServer.getObjectClass(lowerOCName); 688 if (objectClass == null) 689 { 690 objectClass = DirectoryServer.getDefaultObjectClass(ocName); 691 } 692 693 objectClasses.put(objectClass, ocName); 694 } 695 } 696 else 697 { 698 AttributeType attrType = DirectoryServer.getAttributeTypeOrDefault(lowerName, attrName); 699 AttributeBuilder builder = new AttributeBuilder(attribute, true); 700 for (Object value : csr.getAttributeValues(attrName)) 701 { 702 ByteString bs; 703 if (value instanceof byte[]) 704 { 705 bs = ByteString.wrap((byte[])value); 706 } 707 else 708 { 709 bs = ByteString.valueOfUtf8(value.toString()); 710 } 711 builder.add(bs); 712 } 713 714 List<Attribute> attrList = builder.toAttributeList(); 715 if (attrType.isOperational()) 716 { 717 operationalAttributes.put(attrType, attrList); 718 } 719 else 720 { 721 userAttributes.put(attrType, attrList); 722 } 723 } 724 } 725 726 return new Entry(dn, objectClasses, userAttributes, operationalAttributes); 727 } 728 729 /** 730 * Parse an AttributeDescription (an attribute type name and its 731 * options). 732 * TODO: make this method in LDIFReader public. 733 * 734 * @param attrDescr 735 * The attribute description to be parsed. 736 * @return A new attribute with no values, representing the 737 * attribute type and its options. 738 */ 739 private static Attribute parseAttrDescription(String attrDescr) 740 { 741 AttributeBuilder builder; 742 int semicolonPos = attrDescr.indexOf(';'); 743 if (semicolonPos > 0) 744 { 745 builder = new AttributeBuilder(attrDescr.substring(0, semicolonPos)); 746 int nextPos = attrDescr.indexOf(';', semicolonPos + 1); 747 while (nextPos > 0) 748 { 749 String option = attrDescr.substring(semicolonPos + 1, nextPos); 750 if (option.length() > 0) 751 { 752 builder.setOption(option); 753 semicolonPos = nextPos; 754 nextPos = attrDescr.indexOf(';', semicolonPos + 1); 755 } 756 } 757 758 String option = attrDescr.substring(semicolonPos + 1); 759 if (option.length() > 0) 760 { 761 builder.setOption(option); 762 } 763 } 764 else 765 { 766 builder = new AttributeBuilder(attrDescr); 767 } 768 769 if(builder.getAttributeType().getSyntax().isBEREncodingRequired()) 770 { 771 //resetting doesn't hurt and returns false. 772 builder.setOption("binary"); 773 } 774 775 return builder.toAttribute(); 776 } 777 778 /** 779 * The main method to test this panel. 780 * @param args the arguments. 781 */ 782 public static void main(String[] args) 783 { 784 // This is a hack to initialize configuration 785 new ConfigFromFile(); 786 final ManageTasksPanel p = new ManageTasksPanel(); 787 Thread t = new Thread(new Runnable() 788 { 789 public void run() 790 { 791 try 792 { 793 // To let the dialog to be displayed 794 Thread.sleep(5000); 795 } 796 catch (Throwable t) 797 { 798 t.printStackTrace(); 799 } 800 while (p.isVisible()) 801 { 802 try 803 { 804 SwingUtilities.invokeLater(new Runnable(){ 805 public void run() 806 { 807 Set<TaskEntry> tasks = p.createRandomTasksList(); 808 p.tableModel.setData(tasks); 809 boolean visible = p.tableModel.getRowCount() > 0; 810 if (visible) 811 { 812 p.updateTableSizes(); 813 } 814 p.tableModel.fireTableDataChanged(); 815 p.lNoTasksFound.setVisible(!visible); 816 p.tableScroll.setVisible(visible); 817 p.cancelTask.setVisible(visible); 818 } 819 }); 820 Thread.sleep(5000); 821 } 822 catch (Exception ex) 823 { 824 ex.printStackTrace(); 825 } 826 } 827 } 828 }); 829 t.start(); 830 831 832 SwingUtilities.invokeLater(new Runnable(){ 833 public void run() 834 { 835 GenericDialog dlg = new GenericDialog(Utilities.createFrame(), p); 836 dlg.setModal(true); 837 dlg.pack(); 838 dlg.setVisible(true); 839 } 840 }); 841 t = null; 842 } 843 844 /** 845 * Displays a dialog allowing the user to select which operations to display. 846 * 847 */ 848 private void operationViewClicked() 849 { 850 if (operationViewDlg == null) 851 { 852 operationViewPanel = MonitoringAttributesViewPanel.createMessageInstance( 853 tableModel.getAllAttributes()); 854 operationViewDlg = new GenericDialog(Utilities.getFrame(this), 855 operationViewPanel); 856 Utilities.centerGoldenMean(operationViewDlg, 857 Utilities.getParentDialog(this)); 858 operationViewDlg.setModal(true); 859 } 860 operationViewPanel.setSelectedAttributes( 861 tableModel.getDisplayedAttributes()); 862 operationViewDlg.setVisible(true); 863 if (!operationViewPanel.isCanceled()) 864 { 865 LinkedHashSet<LocalizableMessage> displayedAttributes = 866 operationViewPanel.getAttributes(); 867 setAttributesToDisplay(displayedAttributes); 868 updateTableSizes(); 869 } 870 } 871 872 /** {@inheritDoc} */ 873 public void configurationChanged(ConfigurationChangeEvent ev) 874 { 875 updateErrorPaneIfServerRunningAndAuthRequired(ev.getNewDescriptor(), 876 INFO_CTRL_PANEL_SCHEDULED_TASK_LIST_REQUIRES_SERVER_RUNNING.get(), 877 INFO_CTRL_PANEL_SCHEDULED_TASK_LIST_AUTHENTICATION.get()); 878 ServerDescriptor server = ev.getNewDescriptor(); 879 final Set<TaskEntry> tasks = server.getTaskEntries(); 880 if (haveChanged(tasks)) 881 { 882 SwingUtilities.invokeLater(new Runnable() 883 { 884 /** {@inheritDoc} */ 885 public void run() 886 { 887 Set<String> selectedIds = getSelectedIds(); 888 tableModel.setData(tasks); 889 boolean visible = tableModel.getRowCount() > 0; 890 if (visible) 891 { 892 updateTableSizes(); 893 setSelectedIds(selectedIds); 894 } 895 else 896 { 897 logsLabel.setVisible(false); 898 logsScroll.setVisible(false); 899 } 900 tableModel.fireTableDataChanged(); 901 lNoTasksFound.setVisible(!visible && 902 !errorPane.isVisible()); 903 tableScroll.setVisible(visible); 904 cancelTask.setVisible(visible); 905 detailsPanel.setVisible(visible); 906 } 907 }); 908 } 909 } 910 911 private boolean haveChanged(final Set<TaskEntry> tasks) 912 { 913 if (tableModel.getRowCount() != tasks.size()) 914 { 915 return true; 916 } 917 for (int i=0; i<tableModel.getRowCount(); i++) 918 { 919 if (!tasks.contains(tableModel.get(i))) 920 { 921 return true; 922 } 923 } 924 return false; 925 } 926 927 private void updateTableSizes() 928 { 929 Utilities.updateTableSizes(taskTable, 5); 930 Utilities.updateScrollMode(tableScroll, taskTable); 931 } 932 933 private void setAttributesToDisplay(LinkedHashSet<LocalizableMessage> attributes) 934 { 935 Set<String> selectedIds = getSelectedIds(); 936 tableModel.setAttributes(attributes); 937 tableModel.forceDataStructureChange(); 938 setSelectedIds(selectedIds); 939 } 940 941 /** 942 * The specific menu bar of this panel. 943 * 944 */ 945 class ManageTasksMenuBar extends MainMenuBar 946 { 947 private static final long serialVersionUID = 5051878116443370L; 948 949 /** 950 * Constructor. 951 * @param info the control panel info. 952 */ 953 public ManageTasksMenuBar(ControlPanelInfo info) 954 { 955 super(info); 956 } 957 958 /** {@inheritDoc} */ 959 @Override 960 protected void addMenus() 961 { 962 add(createViewMenuBar()); 963 add(createHelpMenuBar()); 964 } 965 966 /** 967 * Creates the view menu bar. 968 * @return the view menu bar. 969 */ 970 @Override 971 protected JMenu createViewMenuBar() 972 { 973 JMenu menu = Utilities.createMenu( 974 INFO_CTRL_PANEL_CONNECTION_HANDLER_VIEW_MENU.get(), 975 INFO_CTRL_PANEL_CONNECTION_HANDLER_VIEW_MENU_DESCRIPTION.get()); 976 menu.setMnemonic(KeyEvent.VK_V); 977 final JMenuItem viewOperations = Utilities.createMenuItem( 978 INFO_CTRL_PANEL_TASK_ATTRIBUTES_VIEW.get()); 979 menu.add(viewOperations); 980 viewOperations.addActionListener(new ActionListener() 981 { 982 public void actionPerformed(ActionEvent ev) 983 { 984 operationViewClicked(); 985 } 986 }); 987 return menu; 988 } 989 } 990 991 private Set<String> getSelectedIds() 992 { 993 Set<String> selectedIds = new HashSet<>(); 994 int[] indexes = taskTable.getSelectedRows(); 995 if (indexes != null) 996 { 997 for (int index : indexes) 998 { 999 TaskEntry taskEntry = tableModel.get(index); 1000 selectedIds.add(taskEntry.getId()); 1001 } 1002 } 1003 return selectedIds; 1004 } 1005 1006 private void setSelectedIds(Set<String> ids) 1007 { 1008 taskTable.getSelectionModel().clearSelection(); 1009 for (int i=0; i<tableModel.getRowCount(); i++) 1010 { 1011 TaskEntry taskEntry = tableModel.get(i); 1012 if (ids.contains(taskEntry.getId())) 1013 { 1014 taskTable.getSelectionModel().addSelectionInterval(i, i); 1015 } 1016 } 1017 } 1018}