001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2008-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2015 ForgeRock AS. 016 */ 017 018package org.opends.guitools.controlpanel.ui; 019 020import static org.opends.messages.AdminToolMessages.*; 021 022import java.awt.Component; 023import java.awt.Dimension; 024import java.awt.GridBagConstraints; 025import java.awt.Insets; 026import java.awt.Point; 027import java.awt.Window; 028import java.awt.event.ActionEvent; 029import java.awt.event.ActionListener; 030import java.awt.event.ItemEvent; 031import java.awt.event.ItemListener; 032import java.util.ArrayList; 033import java.util.HashMap; 034 035import javax.swing.Box; 036import javax.swing.DefaultComboBoxModel; 037import javax.swing.ImageIcon; 038import javax.swing.JButton; 039import javax.swing.JComboBox; 040import javax.swing.JLabel; 041import javax.swing.JMenuItem; 042import javax.swing.JPopupMenu; 043import javax.swing.JScrollPane; 044import javax.swing.JSeparator; 045import javax.swing.JSplitPane; 046import javax.swing.JTree; 047import javax.swing.SwingUtilities; 048import javax.swing.border.EmptyBorder; 049import javax.swing.event.TreeSelectionEvent; 050import javax.swing.event.TreeSelectionListener; 051import javax.swing.tree.DefaultMutableTreeNode; 052import javax.swing.tree.DefaultTreeModel; 053import javax.swing.tree.TreeNode; 054import javax.swing.tree.TreePath; 055 056import org.opends.guitools.controlpanel.browser.IconPool; 057import org.opends.guitools.controlpanel.datamodel.AbstractIndexDescriptor; 058import org.opends.guitools.controlpanel.datamodel.BackendDescriptor; 059import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; 060import org.opends.guitools.controlpanel.datamodel.IndexDescriptor; 061import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; 062import org.opends.guitools.controlpanel.datamodel.VLVIndexDescriptor; 063import org.opends.guitools.controlpanel.event.*; 064import org.opends.guitools.controlpanel.task.DeleteIndexTask; 065import org.opends.guitools.controlpanel.task.Task; 066import org.opends.guitools.controlpanel.ui.components.CustomTree; 067import org.opends.guitools.controlpanel.ui.components.TreePanel; 068import org.opends.guitools.controlpanel.ui.nodes.AbstractIndexTreeNode; 069import org.opends.guitools.controlpanel.ui.nodes.CategoryTreeNode; 070import org.opends.guitools.controlpanel.ui.nodes.IndexTreeNode; 071import org.opends.guitools.controlpanel.ui.nodes.VLVIndexTreeNode; 072import org.opends.guitools.controlpanel.ui.renderer.TreeCellRenderer; 073import org.opends.guitools.controlpanel.util.Utilities; 074import org.opends.guitools.controlpanel.util.ViewPositions; 075import org.forgerock.i18n.LocalizableMessage; 076 077/** 078 * The pane that is displayed when the user clicks on 'Browse Indexes'. 079 * 080 */ 081public class BrowseIndexPanel extends StatusGenericPanel 082implements IndexModifiedListener 083{ 084 private static final long serialVersionUID = 4560020571983291585L; 085 086 private JComboBox backends; 087 private JLabel lNoBackendsFound; 088 089 private IndexBrowserRightPanel entryPane; 090 private TreePanel treePane; 091 092 private JScrollPane treeScroll; 093 094 private JButton newIndex; 095 private JButton newVLVIndex; 096 097 private CategoryTreeNode standardIndexes = new CategoryTreeNode( 098 INFO_CTRL_PANEL_INDEXES_CATEGORY_NODE.get()); 099 private CategoryTreeNode vlvIndexes = new CategoryTreeNode( 100 INFO_CTRL_PANEL_VLV_INDEXES_CATEGORY_NODE.get()); 101 102 private AbstractIndexDescriptor lastCreatedIndex; 103 104 private TreePath lastIndexTreePath; 105 106 private CategoryTreeNode[] categoryNodes = { 107 standardIndexes, vlvIndexes 108 }; 109 110 private JMenuItem deleteMenuItem; 111 112 private GenericDialog newIndexDialog; 113 private NewIndexPanel newIndexPanel; 114 private GenericDialog newVLVIndexDialog; 115 private NewVLVIndexPanel newVLVIndexPanel; 116 117 private boolean ignoreSelectionEvents; 118 119 private boolean firstTreeRepopulate = true; 120 121 /** 122 * Default constructor. 123 * 124 */ 125 public BrowseIndexPanel() 126 { 127 super(); 128 createLayout(); 129 } 130 131 /** {@inheritDoc} */ 132 public boolean requiresBorder() 133 { 134 return false; 135 } 136 137 /** {@inheritDoc} */ 138 public boolean requiresScroll() 139 { 140 return false; 141 } 142 143 /** {@inheritDoc} */ 144 public void toBeDisplayed(boolean visible) 145 { 146 super.toBeDisplayed(visible); 147 Window w = Utilities.getParentDialog(this); 148 if (w instanceof GenericDialog) 149 { 150 ((GenericDialog)w).getRootPane().setDefaultButton(null); 151 } 152 else if (w instanceof GenericFrame) 153 { 154 ((GenericFrame)w).getRootPane().setDefaultButton(null); 155 } 156 } 157 158 /** 159 * Creates the layout of the panel (but the contents are not populated here). 160 */ 161 private void createLayout() 162 { 163 setBackground(ColorAndFontConstants.greyBackground); 164 GridBagConstraints gbc = new GridBagConstraints(); 165 gbc.anchor = GridBagConstraints.WEST; 166 gbc.gridx = 0; 167 gbc.gridy = 0; 168 gbc.gridwidth = 5; 169 gbc.weightx = 1.0; 170 gbc.fill = GridBagConstraints.BOTH; 171 addErrorPane(gbc); 172 173 gbc.gridy ++; 174 gbc.gridwidth = 1; 175 gbc.weightx = 0; 176 gbc.fill = GridBagConstraints.NONE; 177 gbc.gridx = 0; 178 gbc.fill = GridBagConstraints.HORIZONTAL; 179 gbc.insets = new Insets(10, 10, 0, 0); 180 JLabel lBackend = 181 Utilities.createPrimaryLabel(INFO_CTRL_PANEL_BACKEND_LABEL.get()); 182 add(lBackend, gbc); 183 184 backends = Utilities.createComboBox(); 185 backends.setModel(new DefaultComboBoxModel(new String[]{})); 186 ItemListener comboListener = new ItemListener() 187 { 188 /** {@inheritDoc} */ 189 public void itemStateChanged(ItemEvent ev) 190 { 191 if (!ignoreSelectionEvents && 192 ev.getStateChange() == ItemEvent.SELECTED) 193 { 194 repopulateTree(treePane.getTree()); 195 } 196 } 197 }; 198 backends.addItemListener(comboListener); 199 gbc.insets.left = 5; 200 gbc.gridx ++; 201 add(backends, gbc); 202 lNoBackendsFound = Utilities.createDefaultLabel( 203 INFO_CTRL_PANEL_NO_BACKENDS_FOUND_LABEL.get()); 204 add(lNoBackendsFound, gbc); 205 lNoBackendsFound.setVisible(false); 206 207 newIndex = Utilities.createButton( 208 INFO_CTRL_PANEL_NEW_INDEX_BUTTON_LABEL.get()); 209 newIndex.setOpaque(false); 210 newIndex.addActionListener(new ActionListener() 211 { 212 /** {@inheritDoc} */ 213 public void actionPerformed(ActionEvent ev) 214 { 215 newIndexClicked(); 216 } 217 }); 218 gbc.gridx ++; 219 gbc.insets.left = 10; 220 add(newIndex, gbc); 221 222 newVLVIndex = Utilities.createButton( 223 INFO_CTRL_PANEL_NEW_VLV_INDEX_BUTTON_LABEL.get()); 224 newVLVIndex.setOpaque(false); 225 newVLVIndex.addActionListener(new ActionListener() 226 { 227 /** {@inheritDoc} */ 228 public void actionPerformed(ActionEvent ev) 229 { 230 newVLVIndexClicked(); 231 } 232 }); 233 gbc.gridx ++; 234 gbc.insets.right = 10; 235 add(newVLVIndex, gbc); 236 gbc.gridx ++; 237 gbc.weightx = 1.0; 238 add(Box.createHorizontalGlue(), gbc); 239 240 gbc.insets = new Insets(10, 0, 0, 0); 241 gbc.gridx = 0; 242 gbc.gridy ++; 243 gbc.weightx = 1.0; 244 gbc.weighty = 1.0; 245 gbc.fill = GridBagConstraints.BOTH; 246 gbc.gridwidth = 5; 247 add(createSplitPane(), gbc); 248 } 249 250 /** {@inheritDoc} */ 251 public LocalizableMessage getTitle() 252 { 253 return INFO_CTRL_PANEL_MANAGE_INDEXES_TITLE.get(); 254 } 255 256 /** {@inheritDoc} */ 257 public Component getPreferredFocusComponent() 258 { 259 return backends; 260 } 261 262 /** {@inheritDoc} */ 263 public void closeClicked() 264 { 265 super.closeClicked(); 266 } 267 268 /** {@inheritDoc} */ 269 public void okClicked() 270 { 271 // No ok button 272 } 273 274 /** {@inheritDoc} */ 275 public GenericDialog.ButtonType getButtonType() 276 { 277 return GenericDialog.ButtonType.CLOSE; 278 } 279 280 private Component createSplitPane() 281 { 282 JSplitPane pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); 283 pane.setOpaque(true); //content panes must be opaque 284 285 treePane = new TreePanel(); 286 Utilities.setBorder(treePane, new EmptyBorder(10, 0, 10, 0)); 287 288 entryPane = new IndexBrowserRightPanel(); 289 treeScroll = Utilities.createScrollPane(treePane); 290 291 entryPane.addIndexSelectionListener(new IndexSelectionListener() 292 { 293 /** {@inheritDoc} */ 294 public void indexSelected(IndexSelectionEvent ev) 295 { 296 AbstractIndexDescriptor index = ev.getIndex(); 297 TreeNode parentNode; 298 if (index instanceof IndexDescriptor) 299 { 300 parentNode = standardIndexes; 301 } 302 else 303 { 304 parentNode = vlvIndexes; 305 } 306 DefaultTreeModel model = 307 (DefaultTreeModel)treePane.getTree().getModel(); 308 int n = model.getChildCount(parentNode); 309 for (int i=0; i<n; i++) 310 { 311 AbstractIndexTreeNode node = 312 (AbstractIndexTreeNode)model.getChild(parentNode, i); 313 if (node.getName().equals(index.getName())) 314 { 315 TreePath newSelectionPath = new TreePath(node.getPath()); 316 treePane.getTree().setSelectionPath(newSelectionPath); 317 treePane.getTree().scrollPathToVisible(newSelectionPath); 318 break; 319 } 320 } 321 } 322 }); 323 324 325// Create a split pane 326 pane.setLeftComponent(treeScroll); 327 pane.setRightComponent(entryPane); 328 pane.setResizeWeight(0.0); 329 330 treePane.getTree().addTreeSelectionListener(new TreeSelectionListener() 331 { 332 /** {@inheritDoc} */ 333 public void valueChanged(TreeSelectionEvent ev) 334 { 335 if (!ignoreSelectionEvents) 336 { 337 TreePath[] paths = treePane.getTree().getSelectionPaths(); 338 339 if (entryPane.mustCheckUnsavedChanges()) 340 { 341 ignoreSelectionEvents = true; 342 treePane.getTree().setSelectionPath(lastIndexTreePath); 343 switch (entryPane.checkUnsavedChanges()) 344 { 345 case DO_NOT_SAVE: 346 break; 347 case SAVE: 348 break; 349 case CANCEL: 350 ignoreSelectionEvents = false; 351 return; 352 } 353 if (paths != null) 354 { 355 treePane.getTree().setSelectionPaths(paths); 356 } 357 else 358 { 359 treePane.getTree().clearSelection(); 360 } 361 ignoreSelectionEvents = false; 362 } 363 364 365 boolean deletableElementsSelected = false; 366 boolean nonDeletableElementsSelected = false; 367 if (paths != null) 368 { 369 for (TreePath path : paths) 370 { 371 Object node = path.getLastPathComponent(); 372 if (node instanceof IndexTreeNode) 373 { 374 IndexDescriptor index = ((IndexTreeNode)node).getIndex(); 375 if (index.isDatabaseIndex()) 376 { 377 nonDeletableElementsSelected = true; 378 } 379 else 380 { 381 deletableElementsSelected = true; 382 } 383 } 384 else if (node instanceof VLVIndexTreeNode) 385 { 386 deletableElementsSelected = true; 387 } 388 } 389 } 390 deleteMenuItem.setEnabled(deletableElementsSelected && 391 !nonDeletableElementsSelected); 392 updateEntryPane(); 393 } 394 } 395 }); 396 DefaultMutableTreeNode root = new DefaultMutableTreeNode("Tree root"); 397 for (DefaultMutableTreeNode node : categoryNodes) 398 { 399 root.add(node); 400 } 401 DefaultTreeModel model = new DefaultTreeModel(root); 402 JTree tree = treePane.getTree(); 403 tree.setModel(model); 404 tree.setRootVisible(false); 405 tree.setVisibleRowCount(20); 406 tree.expandPath(new TreePath(root)); 407 tree.setCellRenderer(new IndexTreeCellRenderer()); 408 addPopupMenu(); 409 410 treeScroll.setPreferredSize( 411 new Dimension(2 * treeScroll.getPreferredSize().width, 412 8 * treeScroll.getPreferredSize().height)); 413 entryPane.setBorder(getRightPanelBorder()); 414 entryPane.setPreferredSize( 415 new Dimension((treeScroll.getPreferredSize().width * 5) / 2, 416 treeScroll.getPreferredSize().height)); 417 pane.setDividerLocation(treeScroll.getPreferredSize().width); 418 entryPane.displayVoid(); 419 return pane; 420 } 421 422 /** {@inheritDoc} */ 423 public void setInfo(ControlPanelInfo info) 424 { 425 super.setInfo(info); 426 treePane.setInfo(info); 427 entryPane.setInfo(info); 428 info.addIndexModifiedListener(this); 429 } 430 431 /** {@inheritDoc} */ 432 public void configurationChanged(ConfigurationChangeEvent ev) 433 { 434 ignoreSelectionEvents = true; 435 ServerDescriptor desc = ev.getNewDescriptor(); 436 updateSimpleBackendComboBoxModel(backends, lNoBackendsFound, 437 desc); 438 refreshContents(desc); 439 } 440 441 /** 442 * Adds a pop up menu. 443 * 444 */ 445 private void addPopupMenu() 446 { 447 final JPopupMenu popup = new JPopupMenu(); 448 JMenuItem menuItem = Utilities.createMenuItem( 449 INFO_CTRL_PANEL_NEW_INDEX_MENU.get()); 450 menuItem.addActionListener(new ActionListener() 451 { 452 /** {@inheritDoc} */ 453 public void actionPerformed(ActionEvent ev) 454 { 455 newIndexClicked(); 456 } 457 }); 458 popup.add(menuItem); 459 menuItem = Utilities.createMenuItem( 460 INFO_CTRL_PANEL_NEW_VLV_INDEX_MENU.get()); 461 menuItem.addActionListener(new ActionListener() 462 { 463 /** {@inheritDoc} */ 464 public void actionPerformed(ActionEvent ev) 465 { 466 newVLVIndexClicked(); 467 } 468 }); 469 popup.add(menuItem); 470 popup.add(new JSeparator()); 471 deleteMenuItem = Utilities.createMenuItem( 472 INFO_CTRL_PANEL_DELETE_INDEX_MENU.get()); 473 deleteMenuItem.addActionListener(new ActionListener() 474 { 475 /** {@inheritDoc} */ 476 public void actionPerformed(ActionEvent ev) 477 { 478 deleteClicked(); 479 } 480 }); 481 popup.add(deleteMenuItem); 482 deleteMenuItem.setEnabled(false); 483 484 ((CustomTree)treePane.getTree()).setPopupMenu(popup); 485 } 486 487 /** 488 * Refresh the contents of the tree. 489 * @param desc the descriptor containing the index configuration. 490 */ 491 private void refreshContents(final ServerDescriptor desc) 492 { 493 SwingUtilities.invokeLater(new Runnable() 494 { 495 /** {@inheritDoc} */ 496 public void run() 497 { 498 repopulateTree(treePane.getTree()); 499 ignoreSelectionEvents = false; 500 boolean userBackendsDefined = backends.getModel().getSize() > 0; 501 newIndex.setEnabled(userBackendsDefined); 502 newVLVIndex.setEnabled(userBackendsDefined); 503 if (!userBackendsDefined) 504 { 505 entryPane.displayVoid(); 506 updateErrorPane(errorPane, 507 ERR_CTRL_PANEL_NO_BACKENDS_FOUND_TITLE.get(), 508 ColorAndFontConstants.errorTitleFont, 509 ERR_CTRL_PANEL_NO_BACKENDS_FOUND_DETAILS.get(), 510 ColorAndFontConstants.defaultFont); 511 errorPane.setVisible(true); 512 } 513 else 514 { 515 errorPane.setVisible(false); 516 } 517 } 518 }); 519 } 520 521 /** {@inheritDoc} */ 522 public void indexModified(IndexModifiedEvent ev) 523 { 524 refreshContents(getInfo().getServerDescriptor()); 525 } 526 527 /** {@inheritDoc} */ 528 public void backendIndexesModified(IndexModifiedEvent ev) 529 { 530 refreshContents(getInfo().getServerDescriptor()); 531 } 532 533 /** 534 * Repopulates the contents of the tree. 535 * @param tree the tree to be repopulated. 536 */ 537 private void repopulateTree(JTree tree) 538 { 539 ignoreSelectionEvents = true; 540 541 final Point currentPosition = treeScroll.getViewport().getViewPosition(); 542 DefaultMutableTreeNode root = getRoot(tree); 543 544 TreePath path = tree.getSelectionPath(); 545 DefaultMutableTreeNode lastSelectedNode = null; 546 if (path != null) 547 { 548 lastSelectedNode = (DefaultMutableTreeNode)path.getLastPathComponent(); 549 } 550 TreePath newSelectionPath = null; 551 552 BackendDescriptor backend = null; 553 String backendName = (String)backends.getSelectedItem(); 554 if (backendName != null) 555 { 556 for (BackendDescriptor b : getInfo().getServerDescriptor().getBackends()) 557 { 558 if (b.getBackendID().equalsIgnoreCase(backendName)) 559 { 560 backend = b; 561 break; 562 } 563 } 564 } 565 566 ArrayList<ArrayList<? extends AbstractIndexTreeNode>> nodes = new ArrayList<>(); 567 ArrayList<IndexTreeNode> standardIndexNodes = new ArrayList<>(); 568 ArrayList<VLVIndexTreeNode> vlvIndexNodes = new ArrayList<>(); 569 nodes.add(standardIndexNodes); 570 nodes.add(vlvIndexNodes); 571 572 if (backend != null) 573 { 574 for (IndexDescriptor index : backend.getIndexes()) 575 { 576 standardIndexNodes.add(new IndexTreeNode(index.getName(), index)); 577 } 578 for (VLVIndexDescriptor index : backend.getVLVIndexes()) 579 { 580 vlvIndexNodes.add(new VLVIndexTreeNode(index.getName(), index)); 581 } 582 } 583 584 585 DefaultTreeModel model = (DefaultTreeModel)tree.getModel(); 586 int i = 0; 587 int positionUnderRoot = 0; 588 for (DefaultMutableTreeNode parent : categoryNodes) 589 { 590 if (nodes.get(i).isEmpty()) 591 { 592 if (root.getIndex(parent) != -1) 593 { 594 model.removeNodeFromParent(parent); 595 parent.removeAllChildren(); 596 } 597 } 598 else 599 { 600 boolean expand = true; 601 if (root.getIndex(parent) == -1) 602 { 603 model.insertNodeInto(parent, root, positionUnderRoot); 604 } 605 else 606 { 607 expand = tree.isExpanded(new TreePath(parent)) || parent.getChildCount() == 0; 608 parent.removeAllChildren(); 609 } 610 for (AbstractIndexTreeNode node : nodes.get(i)) 611 { 612 parent.add(node); 613 if (newSelectionPath == null && 614 (lastSelectedNode != null || lastCreatedIndex != null)) 615 { 616 if (lastCreatedIndex != null) 617 { 618 if (node instanceof IndexTreeNode && 619 lastCreatedIndex instanceof IndexDescriptor) 620 { 621 if (node.getName().equals(lastCreatedIndex.getName())) 622 { 623 newSelectionPath = new TreePath(node.getPath()); 624 lastCreatedIndex = null; 625 } 626 } 627 else if (node instanceof VLVIndexTreeNode 628 && lastCreatedIndex instanceof VLVIndexDescriptor 629 && node.getName().equals(lastCreatedIndex.getName())) 630 { 631 newSelectionPath = new TreePath(node.getPath()); 632 lastCreatedIndex = null; 633 } 634 } 635 else if (node.getName().equals(lastSelectedNode.getUserObject())) 636 { 637 newSelectionPath = new TreePath(node.getPath()); 638 } 639 } 640 } 641 model.nodeStructureChanged(parent); 642 if (expand) 643 { 644 tree.expandPath(new TreePath(parent.getPath())); 645 } 646 positionUnderRoot++; 647 } 648 i++; 649 } 650 651 if (newSelectionPath == null && firstTreeRepopulate) 652 { 653 newSelectionPath = new TreePath(standardIndexes.getPath()); 654 } 655 if (newSelectionPath != null) 656 { 657 tree.setSelectionPath(newSelectionPath); 658 tree.scrollPathToVisible(newSelectionPath); 659 } 660 661 updateEntryPane(); 662 663 SwingUtilities.invokeLater(new Runnable() 664 { 665 public void run() 666 { 667 if (firstTreeRepopulate) 668 { 669 treeScroll.getViewport().setViewPosition(new Point(0, 0)); 670 } 671 else 672 { 673 treeScroll.getViewport().setViewPosition(currentPosition); 674 } 675 } 676 }); 677 firstTreeRepopulate = false; 678 ignoreSelectionEvents = false; 679 } 680 681 /** 682 * Updates the contents of the right panel. 683 * 684 */ 685 private void updateEntryPane() 686 { 687 ViewPositions pos = Utilities.getViewPositions(entryPane); 688 TreePath[] paths = treePane.getTree().getSelectionPaths(); 689 TreePath path = null; 690 if (paths != null && paths.length == 1) 691 { 692 path = paths[0]; 693 } 694 lastIndexTreePath = path; 695 if (path != null) 696 { 697 Object node = path.getLastPathComponent(); 698 if (node instanceof IndexTreeNode) 699 { 700 entryPane.updateStandardIndex( 701 ((IndexTreeNode)node).getIndex()); 702 } 703 else if (node instanceof VLVIndexTreeNode) 704 { 705 entryPane.updateVLVIndex(((VLVIndexTreeNode)node).getIndex()); 706 } 707 else if (node == standardIndexes) 708 { 709 String backendName = (String)backends.getSelectedItem(); 710 entryPane.updateBackendIndexes(backendName); 711 } 712 else if (node == vlvIndexes) 713 { 714 String backendName = (String)backends.getSelectedItem(); 715 entryPane.updateBackendVLVIndexes(backendName); 716 } 717 else 718 { 719 entryPane.displayVoid(); 720 } 721 } 722 else 723 { 724 if (paths != null && paths.length > 1) 725 { 726 entryPane.displayMultiple(); 727 } 728 else 729 { 730 entryPane.displayVoid(); 731 } 732 } 733 Utilities.updateViewPositions(pos); 734 } 735 736 private DefaultMutableTreeNode getRoot(JTree tree) 737 { 738 return (DefaultMutableTreeNode)tree.getModel().getRoot(); 739 } 740 741 private void newIndexClicked() 742 { 743 if (newIndexPanel == null) 744 { 745 newIndexPanel = 746 new NewIndexPanel((String)backends.getSelectedItem(), 747 Utilities.getParentDialog(this)); 748 newIndexPanel.setInfo(getInfo()); 749 newIndexDialog = new GenericDialog(null, newIndexPanel); 750 Utilities.centerGoldenMean(newIndexDialog, 751 Utilities.getParentDialog(this)); 752 newIndexPanel.addConfigurationElementCreatedListener( 753 new ConfigurationElementCreatedListener() 754 { 755 public void elementCreated(ConfigurationElementCreatedEvent ev) 756 { 757 Object o = ev.getConfigurationObject(); 758 if (o instanceof AbstractIndexDescriptor) 759 { 760 lastCreatedIndex = (AbstractIndexDescriptor)o; 761 } 762 } 763 }); 764 } 765 else if (!newIndexDialog.isVisible()) 766 { 767 String backendID = (String)backends.getSelectedItem(); 768 for (BackendDescriptor backend : 769 getInfo().getServerDescriptor().getBackends()) 770 { 771 if (backend.getBackendID().equalsIgnoreCase(backendID)) 772 { 773 newIndexPanel.update(backend); 774 break; 775 } 776 } 777 } 778 newIndexDialog.setVisible(true); 779 } 780 781 private void newVLVIndexClicked() 782 { 783 if (newVLVIndexPanel == null) 784 { 785 newVLVIndexPanel = 786 new NewVLVIndexPanel((String)backends.getSelectedItem(), 787 Utilities.getParentDialog(this)); 788 newVLVIndexPanel.setInfo(getInfo()); 789 newVLVIndexDialog = new GenericDialog(null, newVLVIndexPanel); 790 Utilities.centerGoldenMean(newVLVIndexDialog, 791 Utilities.getParentDialog(this)); 792 newVLVIndexPanel.addConfigurationElementCreatedListener( 793 new ConfigurationElementCreatedListener() 794 { 795 /** {@inheritDoc} */ 796 public void elementCreated(ConfigurationElementCreatedEvent ev) 797 { 798 Object o = ev.getConfigurationObject(); 799 if (o instanceof AbstractIndexDescriptor) 800 { 801 lastCreatedIndex = (AbstractIndexDescriptor)o; 802 } 803 } 804 }); 805 } 806 else if (!newVLVIndexDialog.isVisible()) 807 { 808 String backendID = (String)backends.getSelectedItem(); 809 for (BackendDescriptor backend : 810 getInfo().getServerDescriptor().getBackends()) 811 { 812 if (backend.getBackendID().equalsIgnoreCase(backendID)) 813 { 814 newVLVIndexPanel.update(backend); 815 break; 816 } 817 } 818 } 819 newVLVIndexDialog.setVisible(true); 820 } 821 822 private void deleteClicked() 823 { 824 ArrayList<LocalizableMessage> errors = new ArrayList<>(); 825 TreePath[] paths = treePane.getTree().getSelectionPaths(); 826 ArrayList<AbstractIndexDescriptor> indexesToDelete = new ArrayList<>(); 827 ArrayList<String> indexesNames = new ArrayList<>(); 828 if (paths != null) 829 { 830 for (TreePath path : paths) 831 { 832 Object node = path.getLastPathComponent(); 833 if (node instanceof IndexTreeNode) 834 { 835 indexesToDelete.add(((IndexTreeNode)node).getIndex()); 836 } 837 else if (node instanceof VLVIndexTreeNode) 838 { 839 indexesToDelete.add(((VLVIndexTreeNode)node).getIndex()); 840 } 841 } 842 } 843 else 844 { 845 errors.add(ERR_CTRL_PANEL_NO_INDEX_SELECTED.get()); 846 } 847 for (AbstractIndexDescriptor index : indexesToDelete) 848 { 849 indexesNames.add(index.getName()); 850 } 851 String nameLabel = Utilities.getStringFromCollection(indexesNames, ", "); 852 String backendName = indexesToDelete.get(0).getBackend().getBackendID(); 853 if (errors.isEmpty()) 854 { 855 ProgressDialog dlg = new ProgressDialog( 856 Utilities.createFrame(), 857 Utilities.getParentDialog(this), 858 INFO_CTRL_PANEL_DELETE_INDEXES_TITLE.get(), getInfo()); 859 DeleteIndexTask newTask = new DeleteIndexTask(getInfo(), dlg, 860 indexesToDelete); 861 for (Task task : getInfo().getTasks()) 862 { 863 task.canLaunch(newTask, errors); 864 } 865 if (errors.isEmpty()) 866 { 867 if (displayConfirmationDialog( 868 INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(), 869 INFO_CTRL_PANEL_CONFIRMATION_INDEXES_DELETE_DETAILS.get(nameLabel, 870 backendName))) 871 { 872 launchOperation(newTask, 873 INFO_CTRL_PANEL_DELETING_INDEXES_SUMMARY.get(), 874 INFO_CTRL_PANEL_DELETING_INDEXES_COMPLETE.get(), 875 INFO_CTRL_PANEL_DELETING_INDEXES_SUCCESSFUL.get(nameLabel, backendName), 876 ERR_CTRL_PANEL_DELETING_INDEXES_ERROR_SUMMARY.get(), 877 ERR_CTRL_PANEL_DELETING_INDEXES_ERROR_DETAILS.get(nameLabel), 878 null, 879 dlg); 880 dlg.setVisible(true); 881 } 882 } 883 } 884 if (!errors.isEmpty()) 885 { 886 displayErrorDialog(errors); 887 } 888 } 889 890 private HashMap<Object, ImageIcon> hmCategoryImages = new HashMap<>(); 891 private HashMap<Class<?>, ImageIcon> hmImages = new HashMap<>(); 892 { 893 Object[] nodes = {standardIndexes, vlvIndexes}; 894 String[] paths = {"ds-idx-folder.png", "ds-vlv-idx-folder.png"}; 895 for (int i=0; i<nodes.length; i++) 896 { 897 hmCategoryImages.put(nodes[i], 898 Utilities.createImageIcon(IconPool.IMAGE_PATH+"/"+paths[i])); 899 } 900 Class<?>[] classes = {IndexTreeNode.class, VLVIndexTreeNode.class}; 901 String[] ocPaths = {"ds-idx.png", "ds-vlv-idx.png"}; 902 for (int i=0; i<classes.length; i++) 903 { 904 hmImages.put(classes[i], 905 Utilities.createImageIcon(IconPool.IMAGE_PATH+"/"+ocPaths[i])); 906 } 907 } 908 909 /** Specific class used to render the nodes in the tree. It uses specific icons for the nodes. */ 910 protected class IndexTreeCellRenderer extends TreeCellRenderer 911 { 912 private ImageIcon readOnlyIndexIcon = 913 Utilities.createImageIcon(IconPool.IMAGE_PATH+"/ds-idx-ro.png"); 914 915 private static final long serialVersionUID = -6953837045703643228L; 916 917 /** {@inheritDoc} */ 918 public Component getTreeCellRendererComponent(JTree tree, Object value, 919 boolean isSelected, boolean isExpanded, boolean isLeaf, int row, 920 boolean hasFocus) 921 { 922 super.getTreeCellRendererComponent(tree, value, isSelected, isExpanded, 923 isLeaf, row, hasFocus); 924 setIcon(getIcon(value)); 925 return this; 926 } 927 928 private ImageIcon getIcon(Object value) 929 { 930 ImageIcon icon = null; 931 if (value instanceof IndexTreeNode 932 && ((IndexTreeNode)value).getIndex().isDatabaseIndex()) 933 { 934 icon = readOnlyIndexIcon; 935 } 936 if (icon == null) 937 { 938 icon = hmImages.get(value.getClass()); 939 if (icon == null) 940 { 941 icon = hmCategoryImages.get(value); 942 } 943 } 944 return icon; 945 } 946 } 947}