From 2bdcb07b1db84f321a3a84988799d2c78b1a1741 Mon Sep 17 00:00:00 2001
From: Gaetan Boismal <gaetan.boismal@forgerock.com>
Date: Fri, 24 Apr 2015 07:53:59 +0000
Subject: [PATCH] OPENDJ-1934 UI: Create/Update VLV indexes

---
 opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Converters.java              |   63 +++++++
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewVLVIndexPanel.java          |  114 +++++--------
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/VLVIndexPanel.java             |   99 ++++++------
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractVLVIndexPanel.java     |  160 ++++++++++++++++---
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/VLVIndexDescriptor.java |    2 
 5 files changed, 285 insertions(+), 153 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Converters.java b/opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Converters.java
index 3891de1..39c073d 100644
--- a/opendj-server-legacy/src/main/java/org/forgerock/opendj/adapter/server3x/Converters.java
+++ b/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);
+      }
+    }
+
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/VLVIndexDescriptor.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/VLVIndexDescriptor.java
index 5af397c..438854d 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/VLVIndexDescriptor.java
+++ b/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())
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractVLVIndexPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractVLVIndexPanel.java
index 07a8f35..1e0b624 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractVLVIndexPanel.java
+++ b/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);
+  }
+
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewVLVIndexPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewVLVIndexPanel.java
index 4656f5b..aab2dc5 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewVLVIndexPanel.java
+++ b/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
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/VLVIndexPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/VLVIndexPanel.java
index 0b2544d..f0e6531 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/VLVIndexPanel.java
+++ b/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))

--
Gitblit v1.10.0