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-2009 Sun Microsystems, Inc. 025 * Portions Copyright 2011-2015 ForgeRock AS 026 */ 027 028package org.opends.guitools.controlpanel.ui; 029 030import static org.opends.guitools.controlpanel.util.Utilities.*; 031import static org.opends.messages.AdminToolMessages.*; 032 033import java.awt.Component; 034import java.awt.GridBagConstraints; 035import java.awt.GridBagLayout; 036import java.awt.Insets; 037import java.awt.event.ActionEvent; 038import java.awt.event.ActionListener; 039import java.util.ArrayList; 040import java.util.Collection; 041import java.util.HashSet; 042import java.util.List; 043import java.util.Set; 044import java.util.TreeSet; 045 046import javax.naming.ldap.InitialLdapContext; 047import javax.swing.Box; 048import javax.swing.DefaultComboBoxModel; 049import javax.swing.JButton; 050import javax.swing.JLabel; 051import javax.swing.JPanel; 052import javax.swing.JScrollPane; 053import javax.swing.SwingConstants; 054import javax.swing.SwingUtilities; 055import javax.swing.border.EmptyBorder; 056import javax.swing.event.DocumentEvent; 057import javax.swing.event.DocumentListener; 058import javax.swing.event.ListDataEvent; 059import javax.swing.event.ListDataListener; 060 061import org.forgerock.i18n.LocalizableMessage; 062import org.forgerock.opendj.adapter.server3x.Converters; 063import org.forgerock.opendj.config.server.ConfigException; 064import org.forgerock.opendj.ldap.SearchScope; 065import org.opends.guitools.controlpanel.datamodel.AbstractIndexDescriptor; 066import org.opends.guitools.controlpanel.datamodel.CategorizedComboBoxElement; 067import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; 068import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; 069import org.opends.guitools.controlpanel.datamodel.VLVIndexDescriptor; 070import org.opends.guitools.controlpanel.datamodel.VLVSortOrder; 071import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; 072import org.opends.guitools.controlpanel.event.ScrollPaneBorderListener; 073import org.opends.guitools.controlpanel.task.DeleteIndexTask; 074import org.opends.guitools.controlpanel.task.Task; 075import org.opends.guitools.controlpanel.util.ConfigReader; 076import org.opends.guitools.controlpanel.util.Utilities; 077import org.opends.server.admin.client.ManagementContext; 078import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor; 079import org.opends.server.admin.client.ldap.LDAPManagementContext; 080import org.opends.server.admin.std.client.BackendVLVIndexCfgClient; 081import org.opends.server.admin.std.client.PluggableBackendCfgClient; 082import org.opends.server.admin.std.client.RootCfgClient; 083import org.opends.server.core.DirectoryServer; 084import org.opends.server.types.DN; 085import org.opends.server.types.OpenDsException; 086 087/** 088 * The panel that displays an existing VLV index (it appears on the right of the 089 * 'Manage Indexes' dialog). 090 */ 091public class VLVIndexPanel extends AbstractVLVIndexPanel 092{ 093 private static final long serialVersionUID = 6333337497315464283L; 094 private static final LocalizableMessage INDEX_MODIFIED = INFO_CTRL_PANEL_INDEX_MODIFIED_MESSAGE.get(); 095 096 private final JButton deleteIndex = Utilities.createButton(INFO_CTRL_PANEL_DELETE_INDEX_LABEL.get()); 097 private final JButton saveChanges = Utilities.createButton(INFO_CTRL_PANEL_SAVE_CHANGES_LABEL.get()); 098 private final JLabel warning = Utilities.createDefaultLabel(); 099 100 private ScrollPaneBorderListener scrollListener; 101 102 private ModifyVLVIndexTask newModifyTask; 103 104 private boolean ignoreCheckSave; 105 106 private VLVIndexDescriptor index; 107 108 /** Default constructor. */ 109 public VLVIndexPanel() 110 { 111 super(null, null); 112 createLayout(); 113 } 114 115 @Override 116 public LocalizableMessage getTitle() 117 { 118 return INFO_CTRL_PANEL_VLV_INDEX_PANEL_TITLE.get(); 119 } 120 121 @Override 122 public Component getPreferredFocusComponent() 123 { 124 return baseDN; 125 } 126 127 @Override 128 public void configurationChanged(ConfigurationChangeEvent ev) 129 { 130 final ServerDescriptor desc = ev.getNewDescriptor(); 131 if (updateLayout(desc)) 132 { 133 LocalizableMessage msg = isLocal() ? INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_FOR_VLV_INDEX_EDITING.get() 134 : INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get(desc.getHostname()); 135 updateErrorPaneIfAuthRequired(desc, msg); 136 SwingUtilities.invokeLater(new Runnable() 137 { 138 @Override 139 public void run() 140 { 141 checkSaveButton(); 142 deleteIndex.setEnabled(!authenticationRequired(desc)); 143 } 144 }); 145 } 146 } 147 148 @Override 149 public void okClicked() 150 { 151 } 152 153 /** 154 * Method used to know if there are unsaved changes or not. It is used by the 155 * index selection listener when the user changes the selection. 156 * 157 * @return <CODE>true</CODE> if there are unsaved changes (and so the 158 * selection of the index should be canceled) and <CODE>false</CODE> 159 * otherwise. 160 */ 161 public boolean mustCheckUnsavedChanges() 162 { 163 return index != null && saveChanges.isVisible() && saveChanges.isEnabled(); 164 } 165 166 /** 167 * Tells whether the user chose to save the changes in the panel, to not save 168 * them or simply cancelled the selection in the tree. 169 * 170 * @return the value telling whether the user chose to save the changes in the 171 * panel, to not save them or simply cancelled the selection change in 172 * the tree. 173 */ 174 public UnsavedChangesDialog.Result checkUnsavedChanges() 175 { 176 UnsavedChangesDialog.Result result; 177 final UnsavedChangesDialog unsavedChangesDlg = new UnsavedChangesDialog(getParentDialog(this), getInfo()); 178 unsavedChangesDlg.setMessage(INFO_CTRL_PANEL_UNSAVED_CHANGES_SUMMARY.get(), 179 INFO_CTRL_PANEL_UNSAVED_INDEX_CHANGES_DETAILS.get(index.getName())); 180 centerGoldenMean(unsavedChangesDlg, getParentDialog(this)); 181 unsavedChangesDlg.setVisible(true); 182 result = unsavedChangesDlg.getResult(); 183 if (result == UnsavedChangesDialog.Result.SAVE) 184 { 185 saveIndex(false); 186 if (newModifyTask == null 187 || newModifyTask.getState() != Task.State.FINISHED_SUCCESSFULLY) // The user data is not valid 188 { 189 result = UnsavedChangesDialog.Result.CANCEL; 190 } 191 } 192 193 return result; 194 } 195 196 private void checkSaveButton() 197 { 198 if (!ignoreCheckSave && index != null) 199 { 200 saveChanges.setEnabled(!authenticationRequired(getInfo().getServerDescriptor()) && isModified()); 201 } 202 } 203 204 /** {@inheritDoc} */ 205 @Override 206 public GenericDialog.ButtonType getButtonType() 207 { 208 return GenericDialog.ButtonType.NO_BUTTON; 209 } 210 211 /** 212 * Creates the layout of the panel (but the contents are not populated here). 213 */ 214 private void createLayout() 215 { 216 GridBagConstraints gbc = new GridBagConstraints(); 217 final JPanel p = new JPanel(new GridBagLayout()); 218 p.setOpaque(false); 219 super.createBasicLayout(p, gbc, true); 220 p.setBorder(new EmptyBorder(10, 10, 10, 10)); 221 gbc = new GridBagConstraints(); 222 gbc.weightx = 1.0; 223 gbc.weighty = 1.0; 224 gbc.fill = GridBagConstraints.BOTH; 225 gbc.gridx = 0; 226 gbc.gridy = 0; 227 final JScrollPane scroll = Utilities.createBorderLessScrollBar(p); 228 scrollListener = ScrollPaneBorderListener.createBottomBorderListener(scroll); 229 add(scroll, gbc); 230 231 gbc.gridy++; 232 gbc.gridx = 0; 233 gbc.weightx = 1.0; 234 gbc.weighty = 0.0; 235 gbc.insets.left = 0; 236 gbc.gridwidth = 2; 237 gbc.weighty = 0.0; 238 gbc.fill = GridBagConstraints.HORIZONTAL; 239 gbc.insets.top = 10; 240 241 gbc.gridwidth = 3; 242 gbc.insets = new Insets(10, 10, 0, 10); 243 add(warning, gbc); 244 Utilities.setWarningLabel(warning, INDEX_MODIFIED); 245 246 gbc.gridy++; 247 final JPanel buttonPanel = new JPanel(new GridBagLayout()); 248 buttonPanel.setOpaque(false); 249 gbc.insets = new Insets(10, 10, 10, 10); 250 add(buttonPanel, gbc); 251 252 gbc.insets = new Insets(0, 0, 0, 0); 253 gbc.gridy = 0; 254 gbc.gridx = 0; 255 gbc.weightx = 0.0; 256 gbc.gridwidth = 1; 257 deleteIndex.setOpaque(false); 258 gbc.insets.left = 0; 259 buttonPanel.add(deleteIndex, gbc); 260 deleteIndex.addActionListener(new ActionListener() 261 { 262 @Override 263 public void actionPerformed(ActionEvent ev) 264 { 265 deleteIndex(); 266 } 267 }); 268 gbc.gridx = 2; 269 gbc.weightx = 1.0; 270 buttonPanel.add(Box.createHorizontalGlue(), gbc); 271 gbc.weightx = 0.0; 272 gbc.insets.left = 10; 273 saveChanges.setOpaque(false); 274 gbc.gridx = 3; 275 buttonPanel.add(saveChanges, gbc); 276 saveChanges.addActionListener(new ActionListener() 277 { 278 @Override 279 public void actionPerformed(ActionEvent ev) 280 { 281 saveIndex(false); 282 } 283 }); 284 285 final DocumentListener documentListener = new DocumentListener() 286 { 287 @Override 288 public void insertUpdate(DocumentEvent ev) 289 { 290 checkSaveButton(); 291 } 292 293 @Override 294 public void changedUpdate(DocumentEvent ev) 295 { 296 checkSaveButton(); 297 } 298 299 @Override 300 public void removeUpdate(DocumentEvent ev) 301 { 302 checkSaveButton(); 303 } 304 }; 305 306 final ActionListener actionListener = new ActionListener() 307 { 308 @Override 309 public void actionPerformed(ActionEvent ev) 310 { 311 checkSaveButton(); 312 } 313 }; 314 315 baseDNs.addActionListener(actionListener); 316 baseObject.addActionListener(actionListener); 317 singleLevel.addActionListener(actionListener); 318 subordinateSubtree.addActionListener(actionListener); 319 wholeSubtree.addActionListener(actionListener); 320 attributes.addActionListener(actionListener); 321 sortOrder.getModel().addListDataListener(new ListDataListener() 322 { 323 @Override 324 public void contentsChanged(ListDataEvent e) 325 { 326 checkSaveButton(); 327 } 328 329 @Override 330 public void intervalAdded(ListDataEvent e) 331 { 332 checkSaveButton(); 333 } 334 335 @Override 336 public void intervalRemoved(ListDataEvent e) 337 { 338 checkSaveButton(); 339 } 340 }); 341 342 baseDN.getDocument().addDocumentListener(documentListener); 343 filter.getDocument().addDocumentListener(documentListener); 344 baseDN.getDocument().addDocumentListener(documentListener); 345 } 346 347 private void deleteIndex() 348 { 349 final List<LocalizableMessage> errors = new ArrayList<>(); 350 final ProgressDialog dlg = new ProgressDialog( 351 createFrame(), getParentDialog(this), INFO_CTRL_PANEL_DELETE_VLV_INDEX_TITLE.get(), getInfo()); 352 final List<AbstractIndexDescriptor> indexesToDelete = new ArrayList<>(); 353 indexesToDelete.add(index); 354 final DeleteIndexTask newTask = new DeleteIndexTask(getInfo(), dlg, indexesToDelete); 355 for (final Task task : getInfo().getTasks()) 356 { 357 task.canLaunch(newTask, errors); 358 } 359 360 if (errors.isEmpty()) 361 { 362 final String indexName = index.getName(); 363 final String backendName = index.getBackend().getBackendID(); 364 if (displayConfirmationDialog(INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(), 365 INFO_CTRL_PANEL_CONFIRMATION_VLV_INDEX_DELETE_DETAILS.get(indexName, backendName))) 366 { 367 launchOperation(newTask, 368 INFO_CTRL_PANEL_DELETING_VLV_INDEX_SUMMARY.get(), 369 INFO_CTRL_PANEL_DELETING_VLV_INDEX_COMPLETE.get(), 370 INFO_CTRL_PANEL_DELETING_VLV_INDEX_SUCCESSFUL.get(indexName, backendName), 371 ERR_CTRL_PANEL_DELETING_VLV_INDEX_ERROR_SUMMARY.get(), 372 ERR_CTRL_PANEL_DELETING_VLV_INDEX_ERROR_DETAILS.get(indexName), 373 null, dlg); 374 dlg.setVisible(true); 375 } 376 } 377 else 378 { 379 displayErrorDialog(errors); 380 } 381 } 382 383 private void saveIndex(boolean modal) 384 { 385 newModifyTask = null; 386 if (!isModified()) 387 { 388 return; 389 } 390 final List<LocalizableMessage> errors = checkErrors(false); 391 392 if (errors.isEmpty()) 393 { 394 final ProgressDialog dlg = 395 new ProgressDialog(getFrame(this), getFrame(this), INFO_CTRL_PANEL_MODIFYING_INDEX_TITLE.get(), getInfo()); 396 dlg.setModal(modal); 397 newModifyTask = new ModifyVLVIndexTask(getInfo(), dlg); 398 for (final Task task : getInfo().getTasks()) 399 { 400 task.canLaunch(newModifyTask, errors); 401 } 402 if (errors.isEmpty() && checkIndexRequired()) 403 { 404 final String indexName = index.getName(); 405 final String backendName = index.getBackend().getBackendID(); 406 launchOperation(newModifyTask, 407 INFO_CTRL_PANEL_MODIFYING_VLV_INDEX_SUMMARY.get(indexName), 408 INFO_CTRL_PANEL_MODIFYING_VLV_INDEX_COMPLETE.get(), 409 INFO_CTRL_PANEL_MODIFYING_VLV_INDEX_SUCCESSFUL.get(indexName, backendName), 410 ERR_CTRL_PANEL_MODIFYING_VLV_INDEX_ERROR_SUMMARY.get(), 411 ERR_CTRL_PANEL_MODIFYING_VLV_INDEX_ERROR_DETAILS.get(indexName), 412 null, dlg); 413 saveChanges.setEnabled(false); 414 dlg.setVisible(true); 415 } 416 } 417 418 if (!errors.isEmpty()) 419 { 420 displayErrorDialog(errors); 421 } 422 } 423 424 /** 425 * Updates the contents of the panel with the provided VLV index. 426 * 427 * @param index 428 * the VLV index descriptor to be used to update the panel. 429 */ 430 public void update(VLVIndexDescriptor index) 431 { 432 ignoreCheckSave = true; 433 readOnlyName.setText(index.getName()); 434 titlePanel.setDetails(LocalizableMessage.raw(index.getName())); 435 if (index.getBackend() != null) 436 { 437 updateBaseDNCombo(index.getBackend()); 438 backendName.setText(index.getBackend().getBackendID()); 439 } 440 final String dn = Utilities.unescapeUtf8(index.getBaseDN().toString()); 441 if (((DefaultComboBoxModel) baseDNs.getModel()).getIndexOf(dn) != -1) 442 { 443 baseDN.setText(""); 444 baseDNs.setSelectedItem(dn); 445 } 446 else 447 { 448 baseDN.setText(dn); 449 baseDNs.setSelectedItem(OTHER_BASE_DN); 450 } 451 452 selectScopeRadioButton(index.getScope()); 453 filter.setText(index.getFilter()); 454 455 // Simulate a remove to update the attribute combo box and add them again. 456 final int indexes[] = new int[sortOrderModel.getSize()]; 457 for (int i = 0; i < indexes.length; i++) 458 { 459 indexes[i] = i; 460 } 461 sortOrder.setSelectedIndices(indexes); 462 remove.doClick(); 463 464 // The list is now empty and the attribute combo properly updated. 465 final DefaultComboBoxModel model = (DefaultComboBoxModel) attributes.getModel(); 466 for (final VLVSortOrder s : index.getSortOrder()) 467 { 468 sortOrderModel.addElement(s); 469 for (int i = 0; i < model.getSize(); i++) 470 { 471 final CategorizedComboBoxElement o = (CategorizedComboBoxElement) model.getElementAt(i); 472 if (o.getType() == CategorizedComboBoxElement.Type.REGULAR && o.getValue().equals(s.getAttributeName())) 473 { 474 model.removeElementAt(i); 475 break; 476 } 477 } 478 } 479 if (model.getSize() > 1) 480 { 481 attributes.setSelectedIndex(1); 482 } 483 484 if (getInfo() != null) 485 { 486 if (getInfo().mustReindex(index)) 487 { 488 setWarningLabel(warning, INDEX_MODIFIED); 489 warning.setVisible(true); 490 warning.setVerticalTextPosition(SwingConstants.TOP); 491 } 492 else 493 { 494 warning.setVisible(false); 495 } 496 } 497 this.index = index; 498 499 ignoreCheckSave = false; 500 checkSaveButton(); 501 502 scrollListener.updateBorder(); 503 } 504 505 private void selectScopeRadioButton(final SearchScope indexScope) 506 { 507 switch (indexScope.asEnum()) 508 { 509 case BASE_OBJECT: 510 baseObject.setSelected(true); 511 break; 512 case SINGLE_LEVEL: 513 singleLevel.setSelected(true); 514 break; 515 case SUBORDINATES: 516 subordinateSubtree.setSelected(true); 517 break; 518 case WHOLE_SUBTREE: 519 wholeSubtree.setSelected(true); 520 break; 521 default: 522 break; 523 } 524 } 525 526 private boolean isModified() 527 { 528 try 529 { 530 return !index.getBaseDN().equals(DN.valueOf(getBaseDN())) || !index.getScope().equals(getScope()) 531 || !index.getFilter().equals(filter.getText().trim()) || !index.getSortOrder().equals(getSortOrder()); 532 } 533 catch (final OpenDsException odse) 534 { 535 // The base DN is not valid. This means that the index has been modified. 536 return true; 537 } 538 } 539 540 /** 541 * The task in charge of modifying the VLV index. 542 */ 543 protected class ModifyVLVIndexTask extends Task 544 { 545 private final Set<String> backendSet; 546 private final String indexName; 547 private final String baseDN; 548 private final String filterValue; 549 private final SearchScope searchScope; 550 private final List<VLVSortOrder> sortOrder; 551 private final String backendID; 552 private final String sortOrderStringValue; 553 private final VLVIndexDescriptor indexToModify; 554 private VLVIndexDescriptor modifiedIndex; 555 556 /** 557 * The constructor of the task. 558 * 559 * @param info 560 * the control panel info. 561 * @param dlg 562 * the progress dialog that shows the progress of the task. 563 */ 564 public ModifyVLVIndexTask(ControlPanelInfo info, ProgressDialog dlg) 565 { 566 super(info, dlg); 567 backendID = index.getBackend().getBackendID(); 568 backendSet = new HashSet<>(); 569 backendSet.add(backendID); 570 indexName = index.getName(); 571 sortOrder = getSortOrder(); 572 baseDN = getBaseDN(); 573 filterValue = filter.getText().trim(); 574 searchScope = getScope(); 575 sortOrderStringValue = getSortOrderStringValue(sortOrder); 576 indexToModify = index; 577 } 578 579 @Override 580 public Type getType() 581 { 582 return Type.MODIFY_INDEX; 583 } 584 585 @Override 586 public Set<String> getBackends() 587 { 588 return backendSet; 589 } 590 591 @Override 592 public LocalizableMessage getTaskDescription() 593 { 594 return INFO_CTRL_PANEL_MODIFY_VLV_INDEX_TASK_DESCRIPTION.get(indexName, backendID); 595 } 596 597 @Override 598 public boolean canLaunch(Task taskToBeLaunched, Collection<LocalizableMessage> incompatibilityReasons) 599 { 600 boolean canLaunch = true; 601 if (state == State.RUNNING && runningOnSameServer(taskToBeLaunched)) 602 { 603 // All the operations are incompatible if they apply to this 604 // backend for safety. This is a short operation so the limitation 605 // has not a lot of impact. 606 final Set<String> backends = new TreeSet<>(taskToBeLaunched.getBackends()); 607 backends.retainAll(getBackends()); 608 if (!backends.isEmpty()) 609 { 610 incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched)); 611 canLaunch = false; 612 } 613 } 614 return canLaunch; 615 } 616 617 private void updateConfiguration() throws OpenDsException, ConfigException 618 { 619 boolean configHandlerUpdated = false; 620 try 621 { 622 if (!isServerRunning()) 623 { 624 configHandlerUpdated = true; 625 getInfo().stopPooling(); 626 if (getInfo().mustDeregisterConfig()) 627 { 628 DirectoryServer.deregisterBaseDN(DN.valueOf("cn=config")); 629 } 630 DirectoryServer.getInstance().initializeConfiguration( 631 org.opends.server.extensions.ConfigFileHandler.class.getName(), ConfigReader.configFile); 632 getInfo().setMustDeregisterConfig(true); 633 } 634 else 635 { 636 SwingUtilities.invokeLater(new Runnable() 637 { 638 @Override 639 public void run() 640 { 641 final List<String> args = getObfuscatedCommandLineArguments(getDSConfigCommandLineArguments()); 642 args.removeAll(getConfigCommandLineArguments()); 643 printEquivalentCommandLine(getConfigCommandLineName(), args, 644 INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_MODIFY_VLV_INDEX.get()); 645 } 646 }); 647 } 648 SwingUtilities.invokeLater(new Runnable() 649 { 650 @Override 651 public void run() 652 { 653 getProgressDialog().appendProgressHtml( 654 Utilities.getProgressWithPoints(INFO_CTRL_PANEL_MODIFYING_VLV_INDEX_PROGRESS.get(indexName), 655 ColorAndFontConstants.progressFont)); 656 } 657 }); 658 659 if (isServerRunning()) 660 { 661 modifyVLVIndexOnline(getInfo().getDirContext()); 662 } 663 else 664 { 665 modifyVLVIndexOffline(backendID, indexName, indexToModify, Converters.from(DN.valueOf(baseDN)), filterValue, 666 searchScope, sortOrder); 667 } 668 SwingUtilities.invokeLater(new Runnable() 669 { 670 /** {@inheritDoc} */ 671 @Override 672 public void run() 673 { 674 getProgressDialog().appendProgressHtml(Utilities.getProgressDone(ColorAndFontConstants.progressFont)); 675 } 676 }); 677 } 678 finally 679 { 680 if (configHandlerUpdated) 681 { 682 DirectoryServer.getInstance().initializeConfiguration(ConfigReader.configClassName, ConfigReader.configFile); 683 getInfo().startPooling(); 684 } 685 } 686 } 687 688 /** 689 * Modifies index using the provided connection. 690 * 691 * @param ctx 692 * the connection to be used to update the index configuration. 693 * @throws OpenDsException 694 * if there is an error updating the server. 695 */ 696 private void modifyVLVIndexOnline(InitialLdapContext ctx) throws OpenDsException 697 { 698 final ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(ctx)); 699 final RootCfgClient root = mCtx.getRootConfiguration(); 700 modifyBackendVLVIndexOnline((PluggableBackendCfgClient) root.getBackend(backendID)); 701 } 702 703 private void modifyBackendVLVIndexOnline(final PluggableBackendCfgClient backend) throws OpenDsException 704 { 705 final BackendVLVIndexCfgClient index = backend.getBackendVLVIndex(indexName); 706 final DN b = DN.valueOf(baseDN); 707 if (!indexToModify.getBaseDN().equals(b)) 708 { 709 index.setBaseDN(b); 710 } 711 712 if (!indexToModify.getFilter().equals(filterValue)) 713 { 714 index.setFilter(filterValue); 715 } 716 717 if (indexToModify.getScope() != searchScope) 718 { 719 index.setScope(VLVIndexDescriptor.getBackendVLVIndexScope(searchScope)); 720 } 721 722 if (!indexToModify.getSortOrder().equals(sortOrder)) 723 { 724 index.setSortOrder(sortOrderStringValue); 725 } 726 index.commit(); 727 } 728 729 @Override 730 protected String getCommandLinePath() 731 { 732 return null; 733 } 734 735 @Override 736 protected ArrayList<String> getCommandLineArguments() 737 { 738 return new ArrayList<>(); 739 } 740 741 private String getConfigCommandLineName() 742 { 743 if (isServerRunning() && isModified()) 744 { 745 return getCommandLinePath("dsconfig"); 746 } 747 return null; 748 } 749 750 @Override 751 public void runTask() 752 { 753 state = State.RUNNING; 754 lastException = null; 755 756 try 757 { 758 updateConfiguration(); 759 modifiedIndex = new VLVIndexDescriptor( 760 indexName, indexToModify.getBackend(), DN.valueOf(baseDN), searchScope, filterValue, sortOrder); 761 getInfo().registerModifiedIndex(modifiedIndex); 762 state = State.FINISHED_SUCCESSFULLY; 763 } 764 catch (final Throwable t) 765 { 766 lastException = t; 767 state = State.FINISHED_WITH_ERROR; 768 } 769 } 770 771 @Override 772 public void postOperation() 773 { 774 if (lastException == null && state == State.FINISHED_SUCCESSFULLY) 775 { 776 rebuildIndexIfNecessary(modifiedIndex, getProgressDialog()); 777 } 778 } 779 780 private List<String> getDSConfigCommandLineArguments() 781 { 782 final List<String> args = new ArrayList<>(); 783 args.add("set-backend-vlv-index-prop"); 784 args.add("--backend-name"); 785 args.add(backendID); 786 787 args.add("--index-name"); 788 args.add(indexName); 789 790 try 791 { 792 final DN b = DN.valueOf(baseDN); 793 if (!indexToModify.getBaseDN().equals(b)) 794 { 795 args.add("--set"); 796 args.add("base-dn:" + baseDN); 797 } 798 } 799 catch (final OpenDsException odse) 800 { 801 throw new RuntimeException("Unexpected error parsing DN " + getBaseDN() + ": " + odse, odse); 802 } 803 804 if (indexToModify.getScope() != searchScope) 805 { 806 args.add("--set"); 807 args.add("scope:" + VLVIndexDescriptor.getBackendVLVIndexScope(searchScope)); 808 } 809 if (!indexToModify.getFilter().equals(filterValue)) 810 { 811 args.add("--set"); 812 args.add("filter:" + filterValue); 813 } 814 815 if (!indexToModify.getSortOrder().equals(sortOrder)) 816 { 817 args.add("--set"); 818 args.add("sort-order:" + sortOrderStringValue); 819 } 820 821 args.addAll(getConnectionCommandLineArguments()); 822 args.add(getNoPropertiesFileArgument()); 823 args.add("--no-prompt"); 824 825 return args; 826 } 827 } 828}