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