mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Gaetan Boismal
24.53.2015 2bdcb07b1db84f321a3a84988799d2c78b1a1741
OPENDJ-1934 UI: Create/Update VLV indexes

Add support for pluggable backend VLV indexes in control panel

* org.forgerock.opendj.adapter.server3x.Converters.java
** Add two methods to convert pluaggable/JE backend VLV index search scope from old to new config framework classes

* org.opends.guitools.controlpanel.datamodel.VLVIndexTypeDescriptor.java
** Rename method getPluggableBackendVLVIndexScope(...) method to getBackendVLVIndexScope(...) in order to be more consistent with config framework classes

* org.opends.guitools.controlpanel.ui.AbstractVLVIndexPanel.java
** Add methods to create/update VLV indexes offline using the new configuration framework
** Remove hardcoded LDIF
** Use the SDK DN class instead of the legacy one

* org.opends.guitools.controlpanel.ui.VLVIndexPanel.java
** Add the pluggable backend indexes support in existing modifyIndex(...) method
** Rename modifyIndex() to modifyVLVIndexOffline()
** Rename modifyIndex(InitialLdapContext ctx) to modifyVLVIndexOnline(InitialContext ctx)
** Change the method process to avoid hardcoded LDIF code (getIndexLDIF() and inner class attribute) usage.
** Use inner class attribute when it is possible
** Remove useless comment

* org.opends.guitools.controlpanel.ui.NewVLVIndexPanel.java
** Add the pluggable backend VLV indexes support in existing createIndex(...) method
** Rename createIndex() to createVLVIndexOffline()
** Rename createIndex(InitialLdapContext ctx) to createVLVIndexOnline(InitialLdapContext ctx)
** Change the method process to avoid hardcoded LDIF code (getIndexLDIF() and inner class attribute) usage.
** Use inner class attribute when it is possible
5 files modified
438 ■■■■■ changed files
opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Converters.java 63 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/VLVIndexDescriptor.java 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractVLVIndexPanel.java 160 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewVLVIndexPanel.java 114 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/VLVIndexPanel.java 99 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Converters.java
@@ -21,10 +21,12 @@
 * CDDL HEADER END
 *
 *
 *      Copyright 2013-2014 ForgeRock AS.
 *      Copyright 2013-2015 ForgeRock AS.
 */
package org.forgerock.opendj.adapter.server3x;
import static org.forgerock.opendj.ldap.LdapException.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -53,6 +55,10 @@
import org.forgerock.opendj.ldap.responses.Responses;
import org.forgerock.opendj.ldap.responses.Result;
import org.forgerock.opendj.ldap.responses.SearchResultEntry;
import org.forgerock.opendj.server.config.meta.BackendVLVIndexCfgDefn;
import org.forgerock.opendj.server.config.meta.LocalDBVLVIndexCfgDefn;
import org.forgerock.util.Reject;
import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
import org.opends.server.core.BindOperation;
import org.opends.server.core.CompareOperation;
import org.opends.server.core.ExtendedOperation;
@@ -66,8 +72,6 @@
import org.opends.server.types.Operation;
import org.opends.server.types.SearchFilter;
import static org.forgerock.opendj.ldap.LdapException.*;
/**
 * Common utility methods.
 */
@@ -733,4 +737,57 @@
        return saslCred.toByteString();
    }
    /**
     * Converts from OpenDJ server
     * {@link org.opends.server.admin.std.meta.BackendVLVIndexCfgDefn.Scope} to
     * {@link org.forgerock.opendj.server.config.meta.BackendVLVIndexCfgDefn.Scope}.
     *
     * @param scope
     *          The scope value.
     * @return The converted scope value.
     */
    public static BackendVLVIndexCfgDefn.Scope from(
        final org.opends.server.admin.std.meta.BackendVLVIndexCfgDefn.Scope scope) {
      Reject.ifNull(scope, "Provided scope to convert is null");
      switch (scope) {
      case BASE_OBJECT:
        return BackendVLVIndexCfgDefn.Scope.BASE_OBJECT;
      case SINGLE_LEVEL:
        return BackendVLVIndexCfgDefn.Scope.SINGLE_LEVEL;
      case SUBORDINATE_SUBTREE:
        return BackendVLVIndexCfgDefn.Scope.SUBORDINATE_SUBTREE;
      case WHOLE_SUBTREE:
        return BackendVLVIndexCfgDefn.Scope.WHOLE_SUBTREE;
      default:
        throw new IllegalArgumentException("Impossible to convert the unknown scope: " + scope);
      }
    }
    /**
     * Converts from OpenDJ server
     * {@link org.opends.server.admin.std.meta.LocalDBVLVIndexCfgDefn.Scope} to
     * {@link org.forgerock.opendj.server.config.meta.LocalDBVLVIndexCfgDefn.Scope}.
     *
     * @param scope
     *          The scope value.
     * @return The converted scope value.
     */
    @RemoveOnceLocalDBBackendIsPluggable
    public static LocalDBVLVIndexCfgDefn.Scope from(
        final org.opends.server.admin.std.meta.LocalDBVLVIndexCfgDefn.Scope scope) {
      Reject.ifNull(scope, "Provided scope to convert is null");
      switch (scope) {
      case BASE_OBJECT:
        return LocalDBVLVIndexCfgDefn.Scope.BASE_OBJECT;
      case SINGLE_LEVEL:
        return LocalDBVLVIndexCfgDefn.Scope.SINGLE_LEVEL;
      case SUBORDINATE_SUBTREE:
        return LocalDBVLVIndexCfgDefn.Scope.SUBORDINATE_SUBTREE;
      case WHOLE_SUBTREE:
        return LocalDBVLVIndexCfgDefn.Scope.WHOLE_SUBTREE;
      default:
        throw new IllegalArgumentException("Impossible to convert the unknown scope: " + scope);
      }
    }
}
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/VLVIndexDescriptor.java
@@ -182,7 +182,7 @@
   * @return the equivalent {@code BackendVLVIndexCfgDefn.Scope} to the provided
   *         search scope.
   */
  public static BackendVLVIndexCfgDefn.Scope getPluggableBackendVLVIndexScope(final SearchScope scope)
  public static BackendVLVIndexCfgDefn.Scope getBackendVLVIndexScope(final SearchScope scope)
  {
    switch (scope.asEnum())
    {
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractVLVIndexPanel.java
@@ -38,6 +38,7 @@
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
@@ -61,7 +62,20 @@
import javax.swing.event.ListSelectionListener;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.adapter.server3x.Converters;
import org.forgerock.opendj.config.LDAPProfile;
import org.forgerock.opendj.config.PropertyException;
import org.forgerock.opendj.config.client.ManagementContext;
import org.forgerock.opendj.config.client.ldap.LDAPManagementContext;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.SearchScope;
import org.forgerock.opendj.server.config.client.BackendCfgClient;
import org.forgerock.opendj.server.config.client.BackendVLVIndexCfgClient;
import org.forgerock.opendj.server.config.client.LocalDBBackendCfgClient;
import org.forgerock.opendj.server.config.client.LocalDBVLVIndexCfgClient;
import org.forgerock.opendj.server.config.client.PluggableBackendCfgClient;
import org.forgerock.opendj.server.config.meta.BackendVLVIndexCfgDefn;
import org.forgerock.opendj.server.config.meta.LocalDBVLVIndexCfgDefn;
import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor;
import org.opends.guitools.controlpanel.datamodel.CategorizedComboBoxElement;
@@ -76,15 +90,16 @@
import org.opends.guitools.controlpanel.ui.renderer.VLVSortOrderRenderer;
import org.opends.guitools.controlpanel.util.LowerCaseComparator;
import org.opends.guitools.controlpanel.util.Utilities;
import org.opends.quicksetup.Installation;
import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
import org.opends.server.config.ConfigException;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
import org.opends.server.types.FilterType;
import org.opends.server.types.LDAPException;
import org.opends.server.types.OpenDsException;
import org.opends.server.types.RawFilter;
import org.opends.server.types.Schema;
import org.opends.server.util.ServerConstants;
/**
 * Abstract class used to re-factor some code between the classes that are used
@@ -214,34 +229,6 @@
  }
  /**
   * Returns the LDIF representing the new index.
   *
   * @param indexName
   *          the name of the index.
   * @return the LDIF representing the new index.
   */
  protected String getIndexLDIF(String indexName)
  {
    final String dn = Utilities.getRDNString("ds-cfg-backend-id", backendName.getText()) + ",cn=Backends,cn=config";
    List<String> lines = new ArrayList<String>();
    lines.add("dn: " + Utilities.getRDNString("ds-cfg-name", indexName) + ",cn=VLV Index," + dn);
    lines.add("objectClass: ds-cfg-local-db-vlv-index");
    lines.add("objectClass: top");
    lines.add("ds-cfg-name: " + indexName);
    lines.add("ds-cfg-filter: " + filter.getText().trim());
    lines.add("ds-cfg-sort-order: " + getSortOrderStringValue(getSortOrder()));
    lines.add("ds-cfg-base-dn: " + getBaseDN());
    lines.add("ds-cfg-scope: " + VLVIndexDescriptor.getLocalDBVLVIndexScope(getScope()));
    StringBuilder sb = new StringBuilder();
    for (String line : lines)
    {
      sb.append(line).append(ServerConstants.EOL);
    }
    return sb.toString();
  }
  /**
   * Returns the scope of the VLV index as it appears on the panel.
   *
   * @return the scope of the VLV index as it appears on the panel.
@@ -646,7 +633,7 @@
    {
      try
      {
        DN.valueOf(baseDN);
        org.opends.server.types.DN.valueOf(baseDN);
      }
      catch (OpenDsException oe)
      {
@@ -1097,4 +1084,115 @@
    gbc.fill = GridBagConstraints.NONE;
    c.add(remove, gbc);
  }
  void createVLVIndexOffline(final String backendName, final String vlvIndexName, final DN baseDN, final String filter,
      final SearchScope searchScope, final List<VLVSortOrder> sortOrder) throws OpenDsException
  {
    updateVLVIndexOffline(backendName, vlvIndexName, null, baseDN, filter, searchScope, sortOrder);
  }
  void modifyVLVIndexOffline(final String backendName, final String vlvIndexName,
      final VLVIndexDescriptor indexToModify, final DN baseDN, final String filter, final SearchScope searchScope,
      final List<VLVSortOrder> sortOrder) throws OpenDsException
  {
    updateVLVIndexOffline(backendName, vlvIndexName, indexToModify, baseDN, filter, searchScope, sortOrder);
  }
  private void updateVLVIndexOffline(final String backendName, final String vlvIndexName,
      final VLVIndexDescriptor indexToModify, final DN baseDN, final String filter, final SearchScope searchScope,
      final List<VLVSortOrder> sortOrder) throws OpenDsException
  {
    getInfo().initializeConfigurationFramework();
    try
    {
      final List<IOException> exceptions = new ArrayList<>();
      final ManagementContext context = LDAPManagementContext.newLDIFManagementContext(
              Installation.getLocal().getCurrentConfigurationFile(), LDAPProfile.getInstance(), exceptions);
      Utilities.throwFirstFrom(exceptions);
      final BackendCfgClient backend = context.getRootConfiguration().getBackend(backendName);
      if (backend instanceof LocalDBBackendCfgClient)
      {
        updateLocalDBVLVIndexOffline((LocalDBBackendCfgClient) backend, vlvIndexName, indexToModify, baseDN, filter,
            searchScope, sortOrder);
      }
      else
      {
        updateVLVBackendIndexOnline((PluggableBackendCfgClient) backend, vlvIndexName, indexToModify, baseDN, filter,
            searchScope, sortOrder);
      }
      context.close();
    }
    catch (final Exception e)
    {
      throw new ConfigException(LocalizableMessage.raw(e.getMessage(), e));
    }
  }
  private void updateVLVBackendIndexOnline(final PluggableBackendCfgClient backend, final String vlvIndexName,
      final VLVIndexDescriptor indexToModify, final DN baseDN, final String filter, final SearchScope searchScope,
      final List<VLVSortOrder> sortOrder) throws Exception
  {
    final boolean isCreation = indexToModify == null;
    final List<PropertyException> exceptions = new ArrayList<>();
    final BackendVLVIndexCfgClient index =
        isCreation ? backend.createBackendVLVIndex(BackendVLVIndexCfgDefn.getInstance(), vlvIndexName, exceptions)
                   : backend.getBackendVLVIndex(vlvIndexName);
    if (isCreation || !indexToModify.getBaseDN().equals(baseDN))
    {
      index.setBaseDN(baseDN);
    }
    if (isCreation || !indexToModify.getFilter().equals(filter))
    {
      index.setFilter(filter);
    }
    if (isCreation || indexToModify.getScope() != searchScope)
    {
      index.setScope(Converters.from(VLVIndexDescriptor.getBackendVLVIndexScope(searchScope)));
    }
    if (isCreation || !indexToModify.getSortOrder().equals(sortOrder))
    {
      index.setSortOrder(getSortOrderStringValue(sortOrder));
    }
    index.commit();
    Utilities.throwFirstFrom(exceptions);
  }
  @RemoveOnceLocalDBBackendIsPluggable
  private void updateLocalDBVLVIndexOffline(final LocalDBBackendCfgClient backend, final String vlvIndexName,
      final VLVIndexDescriptor indexToModify, final DN baseDN, final String filter, final SearchScope searchScope,
      final List<VLVSortOrder> sortOrder) throws Exception
  {
    final boolean isCreation = indexToModify == null;
    final List<PropertyException> exceptions = new ArrayList<>();
    final LocalDBVLVIndexCfgClient index =
        isCreation ? backend.createLocalDBVLVIndex(LocalDBVLVIndexCfgDefn.getInstance(), vlvIndexName, exceptions)
                   : backend.getLocalDBVLVIndex(vlvIndexName);
    if (isCreation || !indexToModify.getBaseDN().equals(baseDN))
    {
      index.setBaseDN(baseDN);
    }
    if (isCreation || !indexToModify.getFilter().equals(filter))
    {
      index.setFilter(filter);
    }
    if (isCreation || !indexToModify.getScope().equals(searchScope))
    {
      index.setScope(Converters.from(VLVIndexDescriptor.getLocalDBVLVIndexScope(searchScope)));
    }
    if (isCreation || !indexToModify.getSortOrder().equals(sortOrder))
    {
      index.setSortOrder(getSortOrderStringValue(sortOrder));
    }
    index.commit();
    Utilities.throwFirstFrom(exceptions);
  }
}
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewVLVIndexPanel.java
@@ -31,8 +31,6 @@
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -44,6 +42,7 @@
import javax.swing.SwingUtilities;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.adapter.server3x.Converters;
import org.forgerock.opendj.ldap.SearchScope;
import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
@@ -51,23 +50,24 @@
import org.opends.guitools.controlpanel.datamodel.VLVIndexDescriptor;
import org.opends.guitools.controlpanel.datamodel.VLVSortOrder;
import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
import org.opends.guitools.controlpanel.task.OfflineUpdateException;
import org.opends.guitools.controlpanel.task.Task;
import org.opends.guitools.controlpanel.util.ConfigReader;
import org.opends.guitools.controlpanel.util.Utilities;
import org.opends.server.admin.PropertyException;
import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
import org.opends.server.admin.client.ldap.LDAPManagementContext;
import org.opends.server.admin.std.client.BackendCfgClient;
import org.opends.server.admin.std.client.BackendVLVIndexCfgClient;
import org.opends.server.admin.std.client.LocalDBBackendCfgClient;
import org.opends.server.admin.std.client.LocalDBVLVIndexCfgClient;
import org.opends.server.admin.std.client.RootCfgClient;
import org.opends.server.admin.std.client.PluggableBackendCfgClient;
import org.opends.server.admin.std.meta.BackendVLVIndexCfgDefn;
import org.opends.server.admin.std.meta.LocalDBVLVIndexCfgDefn;
import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.OpenDsException;
import org.opends.server.util.LDIFReader;
/**
 * Panel that appears when the user defines a new VLV index.
@@ -170,7 +170,6 @@
    private final String baseDN;
    private final String filterValue;
    private final String backendID;
    private final String ldif;
    private final String sortOrderStringValue;
    private VLVIndexDescriptor newIndex;
@@ -193,7 +192,6 @@
      filterValue = filter.getText().trim();
      searchScope = getScope();
      backendID = backendName.getText();
      ldif = getIndexLDIF(indexName);
      sortOrderStringValue = getSortOrderStringValue(sortOrder);
    }
@@ -274,15 +272,15 @@
                  INFO_CTRL_PANEL_CREATING_NEW_VLV_INDEX_PROGRESS.get(indexName), ColorAndFontConstants.progressFont));
          }
        });
        if (isServerRunning())
        {
          // Create additional indexes and display the equivalent command.
          // Everything is done in the method createAdditionalIndexes
          createIndex(getInfo().getDirContext());
          createVLVIndexOnline(getInfo().getDirContext());
        }
        else
        {
          createIndex();
          createVLVIndexOffline(
              backendID, indexName, Converters.from(DN.valueOf(baseDN)), filterValue, searchScope, sortOrder);
        }
        SwingUtilities.invokeLater(new Runnable()
        {
@@ -303,66 +301,46 @@
      }
    }
    private void createIndex() throws OpenDsException
    {
      LDIFImportConfig ldifImportConfig = null;
      try
      {
        ldifImportConfig = new LDIFImportConfig(new StringReader(getLDIF()));
        final LDIFReader reader = new LDIFReader(ldifImportConfig);
        Entry backendConfigEntry;
        while ((backendConfigEntry = reader.readEntry()) != null)
        {
          DirectoryServer.getConfigHandler().addEntry(backendConfigEntry, null);
        }
        DirectoryServer.getConfigHandler().writeUpdatedConfig();
      }
      catch (final IOException ioe)
      {
        throw new OfflineUpdateException(ERR_CTRL_PANEL_ERROR_UPDATING_CONFIGURATION.get(ioe), ioe);
      }
      finally
      {
        if (ldifImportConfig != null)
        {
          ldifImportConfig.close();
        }
      }
    }
    private String getLDIF() throws DirectoryException
    {
      final String topEntryDN =
          "cn=VLV Index," + getRDNString("ds-cfg-backend-id", backendName.getText()) + ",cn=Backends,cn=config";
      final boolean topEntryExists = DirectoryServer.getConfigHandler().entryExists(DN.valueOf(topEntryDN));
      if (!topEntryExists)
      {
        return makeLdif(
            "dn: " + topEntryDN,
            "objectClass: top",
            "objectClass: ds-cfg-branch",
            "cn: VLV Index",
            "")
            + ldif;
      }
      return ldif;
    }
    private void createIndex(InitialLdapContext ctx) throws OpenDsException
    private void createVLVIndexOnline(InitialLdapContext ctx) throws OpenDsException
    {
      final ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(ctx));
      final RootCfgClient root = mCtx.getRootConfiguration();
      final LocalDBBackendCfgClient backend = (LocalDBBackendCfgClient) root.getBackend(backendName.getText());
      final LocalDBVLVIndexCfgDefn provider = LocalDBVLVIndexCfgDefn.getInstance();
      final LocalDBVLVIndexCfgClient index = backend.createLocalDBVLVIndex(provider, name.getText(), null);
      final BackendCfgClient backend = mCtx.getRootConfiguration().getBackend(backendName.getText());
      index.setFilter(filter.getText().trim());
      index.setSortOrder(getSortOrderStringValue(getSortOrder()));
      if (backend instanceof LocalDBBackendCfgClient)
      {
        createLocalDBVLVIndexOnline((LocalDBBackendCfgClient) backend);
        return;
      }
      createBackendVLVIndexOnline((PluggableBackendCfgClient) backend);
    }
    private void createBackendVLVIndexOnline(final PluggableBackendCfgClient backend) throws OpenDsException
    {
      final List<PropertyException> exceptions = new ArrayList<>();
      final BackendVLVIndexCfgClient index =
          backend.createBackendVLVIndex(BackendVLVIndexCfgDefn.getInstance(), name.getText(), exceptions);
      index.setFilter(filterValue);
      index.setSortOrder(sortOrderStringValue);
      index.setBaseDN(DN.valueOf(getBaseDN()));
      index.setScope(VLVIndexDescriptor.getBackendVLVIndexScope(getScope()));
      index.commit();
      Utilities.throwFirstFrom(exceptions);
    }
    @RemoveOnceLocalDBBackendIsPluggable
    private void createLocalDBVLVIndexOnline(final LocalDBBackendCfgClient backend) throws OpenDsException
    {
      final List<PropertyException> exceptions = new ArrayList<>();
      final LocalDBVLVIndexCfgClient index =
          backend.createLocalDBVLVIndex(LocalDBVLVIndexCfgDefn.getInstance(), name.getText(), exceptions);
      index.setFilter(filterValue);
      index.setSortOrder(sortOrderStringValue);
      index.setBaseDN(DN.valueOf(getBaseDN()));
      index.setScope(VLVIndexDescriptor.getLocalDBVLVIndexScope(getScope()));
      index.commit();
      Utilities.throwFirstFrom(exceptions);
    }
    @Override
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/VLVIndexPanel.java
@@ -36,8 +36,6 @@
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -61,6 +59,7 @@
import javax.swing.event.ListDataListener;
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.opendj.adapter.server3x.Converters;
import org.forgerock.opendj.config.server.ConfigException;
import org.forgerock.opendj.ldap.SearchScope;
import org.opends.guitools.controlpanel.datamodel.AbstractIndexDescriptor;
@@ -72,24 +71,22 @@
import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
import org.opends.guitools.controlpanel.event.ScrollPaneBorderListener;
import org.opends.guitools.controlpanel.task.DeleteIndexTask;
import org.opends.guitools.controlpanel.task.OfflineUpdateException;
import org.opends.guitools.controlpanel.task.Task;
import org.opends.guitools.controlpanel.util.ConfigReader;
import org.opends.guitools.controlpanel.util.Utilities;
import org.opends.server.admin.client.ManagementContext;
import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
import org.opends.server.admin.client.ldap.LDAPManagementContext;
import org.opends.server.admin.std.client.BackendCfgClient;
import org.opends.server.admin.std.client.BackendVLVIndexCfgClient;
import org.opends.server.admin.std.client.LocalDBBackendCfgClient;
import org.opends.server.admin.std.client.LocalDBVLVIndexCfgClient;
import org.opends.server.admin.std.client.PluggableBackendCfgClient;
import org.opends.server.admin.std.client.RootCfgClient;
import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
import org.opends.server.core.DirectoryServer;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.LDIFImportConfig;
import org.opends.server.types.OpenDsException;
import org.opends.server.util.LDIFReader;
import com.forgerock.opendj.cli.CommandBuilder;
/**
 * The panel that displays an existing VLV index (it appears on the right of the
@@ -557,7 +554,6 @@
    private final List<VLVSortOrder> sortOrder;
    private final String backendID;
    private final String sortOrderStringValue;
    private final String ldif;
    private final VLVIndexDescriptor indexToModify;
    private VLVIndexDescriptor modifiedIndex;
@@ -581,7 +577,6 @@
      filterValue = filter.getText().trim();
      searchScope = getScope();
      sortOrderStringValue = getSortOrderStringValue(sortOrder);
      ldif = getIndexLDIF(indexName);
      indexToModify = index;
    }
@@ -664,15 +659,15 @@
                    ColorAndFontConstants.progressFont));
          }
        });
        if (isServerRunning())
        {
          // Create additional indexes and display the equivalent command.
          // Everything is done in the method createAdditionalIndexes
          modifyIndex(getInfo().getDirContext());
          modifyVLVIndexOnline(getInfo().getDirContext());
        }
        else
        {
          modifyIndex();
          modifyVLVIndexOffline(backendID, indexName, indexToModify, Converters.from(DN.valueOf(baseDN)), filterValue,
              searchScope, sortOrder);
        }
        SwingUtilities.invokeLater(new Runnable()
        {
@@ -694,31 +689,6 @@
      }
    }
    private void modifyIndex() throws OpenDsException, ConfigException
    {
      LDIFImportConfig ldifImportConfig = null;
      try
      {
        ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
        final LDIFReader reader = new LDIFReader(ldifImportConfig);
        final Entry newConfigEntry = reader.readEntry();
        final Entry oldEntry = DirectoryServer.getConfigEntry(newConfigEntry.getName()).getEntry();
        DirectoryServer.getConfigHandler().replaceEntry(oldEntry, newConfigEntry, null);
        DirectoryServer.getConfigHandler().writeUpdatedConfig();
      }
      catch (final IOException ioe)
      {
        throw new OfflineUpdateException(ERR_CTRL_PANEL_ERROR_UPDATING_CONFIGURATION.get(ioe), ioe);
      }
      finally
      {
        if (ldifImportConfig != null)
        {
          ldifImportConfig.close();
        }
      }
    }
    /**
     * Modifies index using the provided connection.
     *
@@ -727,20 +697,49 @@
     * @throws OpenDsException
     *           if there is an error updating the server.
     */
    private void modifyIndex(InitialLdapContext ctx) throws OpenDsException
    private void modifyVLVIndexOnline(InitialLdapContext ctx) throws OpenDsException
    {
      final StringBuilder sb = new StringBuilder();
      sb.append(getConfigCommandLineName());
      final Collection<String> args = getObfuscatedCommandLineArguments(getDSConfigCommandLineArguments());
      for (final String arg : args)
      {
        sb.append(" ");
        sb.append(CommandBuilder.escapeValue(arg));
      }
      final ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(ctx));
      final RootCfgClient root = mCtx.getRootConfiguration();
      final LocalDBBackendCfgClient backend = (LocalDBBackendCfgClient) root.getBackend(backendID);
      final BackendCfgClient backend = root.getBackend(backendID);
      if (backend instanceof LocalDBBackendCfgClient)
      {
        modifyLocalDBVLVIndexOnline((LocalDBBackendCfgClient) backend);
        return;
      }
      modifyBackendVLVIndexOnline((PluggableBackendCfgClient) backend);
    }
    private void modifyBackendVLVIndexOnline(final PluggableBackendCfgClient backend) throws OpenDsException
    {
      final BackendVLVIndexCfgClient index = backend.getBackendVLVIndex(indexName);
      final DN b = DN.valueOf(baseDN);
      if (!indexToModify.getBaseDN().equals(b))
      {
        index.setBaseDN(b);
      }
      if (!indexToModify.getFilter().equals(filterValue))
      {
        index.setFilter(filterValue);
      }
      if (indexToModify.getScope() != searchScope)
      {
        index.setScope(VLVIndexDescriptor.getBackendVLVIndexScope(searchScope));
      }
      if (!indexToModify.getSortOrder().equals(sortOrder))
      {
        index.setSortOrder(sortOrderStringValue);
      }
      index.commit();
    }
    @RemoveOnceLocalDBBackendIsPluggable
    private void modifyLocalDBVLVIndexOnline(final LocalDBBackendCfgClient backend) throws OpenDsException
    {
      final LocalDBVLVIndexCfgClient index = backend.getLocalDBVLVIndex(indexName);
      final DN b = DN.valueOf(baseDN);
      if (!indexToModify.getBaseDN().equals(b))