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