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

---
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/IndexTypeDescriptor.java |  134 ++++++++-----
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractIndexPanel.java         |  107 ++++++++++
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java    |   38 +++
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewIndexPanel.java              |  156 ++++-----------
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java                |   19 +
 opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/IndexPanel.java                 |  122 +++--------
 6 files changed, 319 insertions(+), 257 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java
index e75feb6..e4b6a69 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/ControlPanelInfo.java
@@ -22,10 +22,16 @@
  *
  *
  *      Copyright 2008-2010 Sun Microsystems, Inc.
- *      Portions Copyright 2014 ForgeRock AS
+ *      Portions Copyright 2014-2015 ForgeRock AS
  */
 package org.opends.guitools.controlpanel.datamodel;
 
+import static org.opends.admin.ads.util.ConnectionUtils.*;
+import static org.opends.guitools.controlpanel.util.Utilities.*;
+
+import static com.forgerock.opendj.cli.Utils.*;
+import static com.forgerock.opendj.util.OperatingSystem.*;
+
 import java.io.File;
 import java.net.InetAddress;
 import java.util.Collection;
@@ -40,6 +46,8 @@
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.i18n.slf4j.LocalizedLogger;
+import org.forgerock.opendj.config.ConfigurationFramework;
+import org.forgerock.opendj.config.server.ConfigException;
 import org.opends.admin.ads.util.ApplicationTrustManager;
 import org.opends.admin.ads.util.ConnectionUtils;
 import org.opends.guitools.controlpanel.browser.IconPool;
@@ -64,12 +72,6 @@
 
 import com.forgerock.opendj.cli.CliConstants;
 
-import static com.forgerock.opendj.cli.Utils.*;
-import static com.forgerock.opendj.util.OperatingSystem.*;
-
-import static org.opends.admin.ads.util.ConnectionUtils.*;
-import static org.opends.guitools.controlpanel.util.Utilities.*;
-
 /**
  * This is the classes that is shared among all the different places in the
  * Control Panel.  It contains information about the server status and
@@ -1343,4 +1345,26 @@
     }
     return connectionWorks;
   }
+
+  /**
+   * Initialize the new configuration framework if needed.
+   *
+   * @throws org.opends.server.config.ConfigException
+   *           If error occurred during the initialization
+   */
+  public void initializeConfigurationFramework() throws org.opends.server.config.ConfigException
+  {
+    if (!ConfigurationFramework.getInstance().isInitialized())
+    {
+      try
+      {
+        ConfigurationFramework.getInstance().initialize();
+      }
+      catch (ConfigException ce)
+      {
+        throw new org.opends.server.config.ConfigException(ce.getMessageObject(), ce);
+      }
+    }
+  }
+
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/IndexTypeDescriptor.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/IndexTypeDescriptor.java
index 972f700..edb83f8 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/IndexTypeDescriptor.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/datamodel/IndexTypeDescriptor.java
@@ -26,6 +26,7 @@
 
 package org.opends.guitools.controlpanel.datamodel;
 
+import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.Set;
 
@@ -33,7 +34,10 @@
 import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn;
 import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
 
-/** Defines the set of values for the index type. */
+/**
+ * Defines the set of values for the index type and provides adaptors to convert
+ * from/to corresponding configuration classes.
+ */
 @RemoveOnceLocalDBBackendIsPluggable
 public enum IndexTypeDescriptor
 {
@@ -41,49 +45,64 @@
    * This index type is used to improve the efficiency of searches using
    * approximate matching search filters.
    */
-  APPROXIMATE("approximate"),
+  APPROXIMATE(LocalDBIndexCfgDefn.IndexType.APPROXIMATE, BackendIndexCfgDefn.IndexType.APPROXIMATE,
+      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.APPROXIMATE,
+      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.APPROXIMATE),
 
   /**
    * This index type is used to improve the efficiency of searches using
    * equality search filters.
    */
-  EQUALITY("equality"),
+  EQUALITY(LocalDBIndexCfgDefn.IndexType.EQUALITY, BackendIndexCfgDefn.IndexType.EQUALITY,
+      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.EQUALITY,
+      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.EQUALITY),
 
   /**
    * This index type is used to improve the efficiency of searches using
    * extensible matching search filters.
    */
-  EXTENSIBLE("extensible"),
+  EXTENSIBLE(LocalDBIndexCfgDefn.IndexType.EXTENSIBLE, BackendIndexCfgDefn.IndexType.EXTENSIBLE,
+      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.EXTENSIBLE,
+      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.EXTENSIBLE),
 
   /**
    * This index type is used to improve the efficiency of searches using
    * "greater than or equal to" or "less then or equal to" search filters.
    */
-  ORDERING("ordering"),
+  ORDERING(LocalDBIndexCfgDefn.IndexType.ORDERING, BackendIndexCfgDefn.IndexType.ORDERING,
+      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.ORDERING,
+      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.ORDERING),
 
   /**
    * This index type is used to improve the efficiency of searches using the
    * presence search filters.
    */
-  PRESENCE("presence"),
+  PRESENCE(LocalDBIndexCfgDefn.IndexType.PRESENCE, BackendIndexCfgDefn.IndexType.PRESENCE,
+      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.PRESENCE,
+      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.PRESENCE),
 
   /**
    * This index type is used to improve the efficiency of searches using
    * substring search filters.
    */
-  SUBSTRING("substring");
+  SUBSTRING(LocalDBIndexCfgDefn.IndexType.SUBSTRING, BackendIndexCfgDefn.IndexType.SUBSTRING,
+      org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType.SUBSTRING,
+      org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType.SUBSTRING);
 
-  private final String name;
+  private final LocalDBIndexCfgDefn.IndexType oldConfigLocalDBIndexType;
+  private final BackendIndexCfgDefn.IndexType oldConfigBackendIndexType;
+  private final org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType localDBIndexType;
+  private final org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType backendIndexType;
 
-  private IndexTypeDescriptor(final String name)
+  private IndexTypeDescriptor(final LocalDBIndexCfgDefn.IndexType oldConfigLocalDBIndexType,
+      final BackendIndexCfgDefn.IndexType oldConfigBackendIndexType,
+      final org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType localDBIndexType,
+      final org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType backendIndexType)
   {
-    this.name = name;
-  }
-
-  @Override
-  public String toString()
-  {
-    return name;
+    this.oldConfigLocalDBIndexType = oldConfigLocalDBIndexType;
+    this.oldConfigBackendIndexType = oldConfigBackendIndexType;
+    this.localDBIndexType = localDBIndexType;
+    this.backendIndexType = backendIndexType;
   }
 
   /**
@@ -95,23 +114,7 @@
    */
   public BackendIndexCfgDefn.IndexType toBackendIndexType()
   {
-    switch (this)
-    {
-    case APPROXIMATE:
-      return BackendIndexCfgDefn.IndexType.APPROXIMATE;
-    case EQUALITY:
-      return BackendIndexCfgDefn.IndexType.EQUALITY;
-    case EXTENSIBLE:
-      return BackendIndexCfgDefn.IndexType.EXTENSIBLE;
-    case ORDERING:
-      return BackendIndexCfgDefn.IndexType.ORDERING;
-    case PRESENCE:
-      return BackendIndexCfgDefn.IndexType.PRESENCE;
-    case SUBSTRING:
-      return BackendIndexCfgDefn.IndexType.SUBSTRING;
-    default:
-      throw new IllegalArgumentException("No BackendIndexCfgDefn.IndexType corresponding to: " + this);
-    }
+    return oldConfigBackendIndexType;
   }
 
   /**
@@ -123,23 +126,7 @@
    */
   public LocalDBIndexCfgDefn.IndexType toLocalDBIndexType()
   {
-    switch (this)
-    {
-    case APPROXIMATE:
-      return LocalDBIndexCfgDefn.IndexType.APPROXIMATE;
-    case EQUALITY:
-      return LocalDBIndexCfgDefn.IndexType.EQUALITY;
-    case EXTENSIBLE:
-      return LocalDBIndexCfgDefn.IndexType.EXTENSIBLE;
-    case ORDERING:
-      return LocalDBIndexCfgDefn.IndexType.ORDERING;
-    case PRESENCE:
-      return LocalDBIndexCfgDefn.IndexType.PRESENCE;
-    case SUBSTRING:
-      return LocalDBIndexCfgDefn.IndexType.SUBSTRING;
-    default:
-      throw new IllegalArgumentException("No LocalDBIndexCfgDefn.IndexType corresponding to: " + this);
-    }
+    return oldConfigLocalDBIndexType;
   }
 
   private static IndexTypeDescriptor fromBackendIndexType(final BackendIndexCfgDefn.IndexType indexType)
@@ -262,4 +249,51 @@
     return indexTypes;
   }
 
+  /**
+   * Convert the provided {@code Set<IndexTypeDescriptor>} to a
+   * {@code Set<org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType>}.
+   *
+   * @param indexTypeDescriptors
+   *          A set of {@code Set<IndexTypeDescriptor>}
+   * @return A set of
+   *         {@code Set<org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType>}
+   *         corresponding to the provided {@code Set<IndexTypeDescriptor>}
+   */
+  @RemoveOnceLocalDBBackendIsPluggable
+  public static Set<org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType> toNewConfigLocalDBIndexTypes(
+      final Set<IndexTypeDescriptor> indexTypeDescriptors)
+  {
+    final Set<org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType> newConfigIndexTypes =
+        new HashSet<org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn.IndexType>();
+    for (IndexTypeDescriptor indexType : indexTypeDescriptors)
+    {
+      newConfigIndexTypes.add(indexType.localDBIndexType);
+    }
+
+    return newConfigIndexTypes;
+  }
+
+  /**
+   * Convert the provided {@code Set<IndexTypeDescriptor>} to a
+   * {@code Set<org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType>}.
+   *
+   * @param indexTypeDescriptors
+   *          A set of {@code Set<IndexTypeDescriptor>}
+   * @return A set of
+   *         {@code Set<org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType>}
+   *         corresponding to the provided {@code Set<IndexTypeDescriptor>}
+   */
+  public static Set<org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType> toNewConfigBackendIndexTypes(
+      final Set<IndexTypeDescriptor> indexTypeDescriptors)
+  {
+    final Set<org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType> newConfigIndexTypes =
+        new HashSet<org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType>();
+    for (IndexTypeDescriptor indexType : indexTypeDescriptors)
+    {
+      newConfigIndexTypes.add(indexType.backendIndexType);
+    }
+
+    return newConfigIndexTypes;
+  }
+
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractIndexPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractIndexPanel.java
index 8103b3e..d9e152f 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractIndexPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/AbstractIndexPanel.java
@@ -31,8 +31,10 @@
 import java.awt.Container;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
@@ -45,12 +47,27 @@
 import javax.swing.JTextField;
 
 import org.forgerock.i18n.LocalizableMessage;
+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.server.config.client.BackendCfgClient;
+import org.forgerock.opendj.server.config.client.BackendIndexCfgClient;
+import org.forgerock.opendj.server.config.client.LocalDBBackendCfgClient;
+import org.forgerock.opendj.server.config.client.LocalDBIndexCfgClient;
+import org.forgerock.opendj.server.config.client.PluggableBackendCfgClient;
+import org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn;
 import org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn;
+import org.opends.guitools.controlpanel.datamodel.IndexDescriptor;
 import org.opends.guitools.controlpanel.datamodel.IndexTypeDescriptor;
 import org.opends.guitools.controlpanel.ui.components.TitlePanel;
 import org.opends.guitools.controlpanel.ui.renderer.CustomListCellRenderer;
 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.types.AttributeType;
+import org.opends.server.types.OpenDsException;
 
 /**
  * Abstract class used to refactor some code between the classes that are used
@@ -353,4 +370,94 @@
 
     return errors;
   }
+
+  void createIndexOffline(final String backendName, final String attributeName,
+      final Set<IndexTypeDescriptor> indexTypes, final int indexEntryLimit) throws OpenDsException
+  {
+    updateIndexOffline(backendName, null, attributeName, indexTypes, indexEntryLimit);
+  }
+
+  void modifyIndexOffline(final String backendName, final String attributeName, final IndexDescriptor indexToModify,
+      final Set<IndexTypeDescriptor> indexTypes, final int indexEntryLimit) throws OpenDsException
+  {
+    updateIndexOffline(backendName, indexToModify, attributeName, indexTypes, indexEntryLimit);
+  }
+
+  private void updateIndexOffline(final String backendName, final IndexDescriptor indexToModify,
+      final String attributeName, final Set<IndexTypeDescriptor> indexTypes, final int indexEntryLimit)
+      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)
+      {
+        updateLocalDBIndexOffline(
+            (LocalDBBackendCfgClient) backend, indexToModify, attributeName, indexTypes, indexEntryLimit);
+      }
+      else
+      {
+        updateBackendIndexOnline(
+            (PluggableBackendCfgClient) backend, indexToModify, attributeName, indexTypes, indexEntryLimit);
+      }
+      context.close();
+    }
+    catch (final Exception e)
+    {
+      throw new ConfigException(LocalizableMessage.raw(e.getMessage(), e));
+    }
+  }
+
+  private void updateBackendIndexOnline(final PluggableBackendCfgClient backend,
+      final IndexDescriptor indexToModify, final String attributeName, final Set<IndexTypeDescriptor> indexTypes,
+      final int indexEntryLimit) throws Exception
+  {
+    final boolean isCreation = indexToModify == null;
+    final List<PropertyException> exceptions = new ArrayList<>();
+    final BackendIndexCfgClient index = isCreation
+        ? backend.createBackendIndex(BackendIndexCfgDefn.getInstance(), attributeName, exceptions)
+        : backend.getBackendIndex(attributeName);
+
+    if (isCreation || indexTypes.equals(indexToModify.getTypes()))
+    {
+      index.setIndexType(IndexTypeDescriptor.toNewConfigBackendIndexTypes(indexTypes));
+    }
+
+    if (indexEntryLimit != index.getIndexEntryLimit())
+    {
+      index.setIndexEntryLimit(indexEntryLimit);
+    }
+    index.commit();
+    Utilities.throwFirstFrom(exceptions);
+ }
+
+  @RemoveOnceLocalDBBackendIsPluggable
+  private void updateLocalDBIndexOffline(final LocalDBBackendCfgClient backend, final IndexDescriptor indexToModify,
+      final String attributeName, final Set<IndexTypeDescriptor> indexTypes, final int indexEntryLimit)
+      throws Exception
+  {
+    final boolean isCreation = indexToModify == null;
+    final List<PropertyException> exceptions = new ArrayList<>();
+    final LocalDBIndexCfgClient index = isCreation
+        ? backend.createLocalDBIndex(LocalDBIndexCfgDefn.getInstance(), attributeName, exceptions)
+        : backend.getLocalDBIndex(attributeName);
+
+    if (isCreation || indexTypes.equals(indexToModify.getTypes()))
+    {
+      index.setIndexType(IndexTypeDescriptor.toNewConfigLocalDBIndexTypes(indexTypes));
+    }
+
+    if (indexEntryLimit != index.getIndexEntryLimit())
+    {
+      index.setIndexEntryLimit(indexEntryLimit);
+    }
+    index.commit();
+    Utilities.throwFirstFrom(exceptions);
+  }
+
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/IndexPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/IndexPanel.java
index 9cc872c..0419190 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/IndexPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/IndexPanel.java
@@ -35,8 +35,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;
@@ -58,7 +56,7 @@
 import javax.swing.event.DocumentListener;
 
 import org.forgerock.i18n.LocalizableMessage;
-import org.forgerock.opendj.config.server.ConfigException;
+import org.forgerock.i18n.slf4j.LocalizedLogger;
 import org.opends.guitools.controlpanel.datamodel.AbstractIndexDescriptor;
 import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
 import org.opends.guitools.controlpanel.datamodel.IndexDescriptor;
@@ -67,26 +65,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.BackendIndexCfgClient;
 import org.opends.server.admin.std.client.LocalDBBackendCfgClient;
 import org.opends.server.admin.std.client.LocalDBIndexCfgClient;
-import org.opends.server.admin.std.client.RootCfgClient;
+import org.opends.server.admin.std.client.PluggableBackendCfgClient;
+import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.AttributeType;
 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 org.opends.server.util.ServerConstants;
-
-import com.forgerock.opendj.cli.CommandBuilder;
 
 /**
  * The panel that displays an existing index (it appears on the right of the
@@ -95,6 +89,8 @@
 public class IndexPanel extends AbstractIndexPanel
 {
   private static final long serialVersionUID = 1439500626486823366L;
+  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
+
   private IndexDescriptor index;
   private ScrollPaneBorderListener scrollListener;
 
@@ -612,13 +608,11 @@
 
         if (isServerRunning())
         {
-          // Create additional indexes and display the equivalent command.
-          // Everything is done in the method createAdditionalIndexes
-          modifyIndex(getInfo().getDirContext());
+          modifyIndexOnline(getInfo().getDirContext());
         }
         else
         {
-          modifyIndex();
+          modifyIndexOffline(backendName, attributeName, indexToModify, indexTypes, entryLimitValue);
         }
 
         SwingUtilities.invokeLater(new Runnable()
@@ -641,66 +635,6 @@
     }
 
     /**
-     * Returns the LDIF representation of the modified index.
-     *
-     * @return the LDIF representation of the modified index.
-     */
-    private String getIndexLDIF()
-    {
-      final String dn = Utilities.getRDNString("ds-cfg-backend-id", backendName) + ",cn=Backends,cn=config";
-      final List<String> lines = new ArrayList<String>();
-      lines.add("dn: " + Utilities.getRDNString("ds-cfg-attribute", attributeName) + ",cn=Index,"+dn);
-      lines.add("objectClass: ds-cfg-local-db-index");
-      lines.add("objectClass: top");
-      lines.add("ds-cfg-attribute: " + attributeName);
-      lines.add("ds-cfg-index-entry-limit: " + entryLimitValue);
-      for (IndexTypeDescriptor type : indexTypes)
-      {
-        lines.add("ds-cfg-index-type: " + type.toLocalDBIndexType());
-      }
-
-      final StringBuilder sb = new StringBuilder();
-      for (final String line : lines)
-      {
-        sb.append(line)
-          .append(ServerConstants.EOL);
-      }
-
-      return sb.toString();
-    }
-
-    private void modifyIndex() throws OpenDsException
-    {
-      LDIFImportConfig ldifImportConfig = null;
-      try
-      {
-        String ldif = getIndexLDIF();
-
-        ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
-        LDIFReader reader = new LDIFReader(ldifImportConfig);
-        Entry newConfigEntry = reader.readEntry();
-        Entry oldEntry = DirectoryServer.getConfigEntry(newConfigEntry.getName()).getEntry();
-        DirectoryServer.getConfigHandler().replaceEntry(oldEntry, newConfigEntry, null);
-        DirectoryServer.getConfigHandler().writeUpdatedConfig();
-      }
-      catch (IOException ioe)
-      {
-        throw new OfflineUpdateException(ERR_CTRL_PANEL_ERROR_UPDATING_CONFIGURATION.get(ioe), ioe);
-      }
-      catch (ConfigException ce)
-      {
-        throw new org.opends.server.config.ConfigException(ce.getMessageObject(), ce);
-      }
-      finally
-      {
-        if (ldifImportConfig != null)
-        {
-          ldifImportConfig.close();
-        }
-      }
-    }
-
-    /**
      * Modifies index using the provided connection.
      *
      * @param ctx
@@ -708,24 +642,42 @@
      * @throws OpenDsException
      *           if there is an error updating the server.
      */
-    private void modifyIndex(InitialLdapContext ctx) throws OpenDsException
+    private void modifyIndexOnline(final InitialLdapContext ctx) throws OpenDsException
     {
-      final StringBuilder sb = new StringBuilder();
-      sb.append(getConfigCommandLineName());
-      Collection<String> args = getObfuscatedCommandLineArguments(getDSConfigCommandLineArguments());
-      for (String arg : args)
+      final ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(ctx));
+      final BackendCfgClient backend = mCtx.getRootConfiguration().getBackend(backendName);
+      if (backend instanceof LocalDBBackendCfgClient)
       {
-        sb.append(" ").append(CommandBuilder.escapeValue(arg));
+        modifyLocalDBIndexOnline((LocalDBBackendCfgClient) backend);
+        return;
+      }
+      modifyBackendIndexOnline((PluggableBackendCfgClient) backend);
+    }
+
+    private void modifyBackendIndexOnline(final PluggableBackendCfgClient backend) throws OpenDsException
+    {
+      final BackendIndexCfgClient index = backend.getBackendIndex(attributeName);
+      if (!indexTypes.equals(indexToModify.getTypes()))
+      {
+        index.setIndexType(IndexTypeDescriptor.toBackendIndexTypes(indexTypes));
       }
 
-      ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(ctx));
-      RootCfgClient root = mCtx.getRootConfiguration();
-      LocalDBBackendCfgClient backend = (LocalDBBackendCfgClient) root.getBackend(backendName);
-      LocalDBIndexCfgClient index = backend.getLocalDBIndex(attributeName);
+      if (entryLimitValue != index.getIndexEntryLimit())
+      {
+        index.setIndexEntryLimit(entryLimitValue);
+      }
+      index.commit();
+    }
+
+    @RemoveOnceLocalDBBackendIsPluggable
+    private void modifyLocalDBIndexOnline(final LocalDBBackendCfgClient backend) throws OpenDsException
+    {
+      final LocalDBIndexCfgClient index = backend.getLocalDBIndex(attributeName);
       if (!indexTypes.equals(indexToModify.getTypes()))
       {
         index.setIndexType(IndexTypeDescriptor.toLocalDBIndexTypes(indexTypes));
       }
+
       if (entryLimitValue != index.getIndexEntryLimit())
       {
         index.setIndexEntryLimit(entryLimitValue);
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewIndexPanel.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewIndexPanel.java
index af332a2..d5afbbf 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewIndexPanel.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/NewIndexPanel.java
@@ -32,8 +32,6 @@
 import java.awt.GridBagConstraints;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
-import java.io.IOException;
-import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -43,16 +41,12 @@
 import java.util.SortedSet;
 import java.util.TreeSet;
 
-import javax.naming.directory.Attributes;
-import javax.naming.directory.BasicAttribute;
-import javax.naming.directory.BasicAttributes;
 import javax.naming.ldap.InitialLdapContext;
 import javax.swing.DefaultComboBoxModel;
 import javax.swing.JCheckBox;
 import javax.swing.SwingUtilities;
 
 import org.forgerock.i18n.LocalizableMessage;
-import org.forgerock.opendj.ldap.ByteString;
 import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
 import org.opends.guitools.controlpanel.datamodel.CategorizedComboBoxElement;
 import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
@@ -60,23 +54,26 @@
 import org.opends.guitools.controlpanel.datamodel.IndexTypeDescriptor;
 import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
 import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
-import org.opends.guitools.controlpanel.task.OfflineUpdateException;
-import org.opends.guitools.controlpanel.task.OnlineUpdateException;
 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.BackendIndexCfgClient;
+import org.opends.server.admin.std.client.LocalDBBackendCfgClient;
+import org.opends.server.admin.std.client.LocalDBIndexCfgClient;
+import org.opends.server.admin.std.client.PluggableBackendCfgClient;
+import org.opends.server.admin.std.meta.BackendIndexCfgDefn;
+import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn;
+import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
 import org.opends.server.core.DirectoryServer;
-import org.opends.server.types.Attribute;
 import org.opends.server.types.AttributeType;
 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.types.Schema;
-import org.opends.server.util.LDIFReader;
-import org.opends.server.util.ServerConstants;
-
-import com.forgerock.opendj.cli.CommandBuilder;
 
 /**
  * Panel that appears when the user defines a new index.
@@ -450,15 +447,14 @@
                 INFO_CTRL_PANEL_CREATING_NEW_INDEX_PROGRESS.get(attributeName), ColorAndFontConstants.progressFont));
           }
         });
+
         if (isServerRunning())
         {
-          // Create additional indexes and display the equivalent command.
-          // Everything is done in the method createAdditionalIndexes
-          createIndex(getInfo().getDirContext());
+          createIndexOnline(getInfo().getDirContext());
         }
         else
         {
-          createIndex();
+          createIndexOffline(backendName.getText(), attributeName, indexTypes, entryLimitValue);
         }
         SwingUtilities.invokeLater(new Runnable()
         {
@@ -479,115 +475,45 @@
       }
     }
 
-    /**
-     * Returns the LDIF representation of the index to be created.
-     *
-     * @return the LDIF representation of the index to be created.
-     */
-    private String getIndexLDIF()
+    private void createIndexOnline(final InitialLdapContext ctx) throws OpenDsException
     {
-      String dn = Utilities.getRDNString("ds-cfg-backend-id", backendName.getText()) + ",cn=Backends,cn=config";
-      ArrayList<String> lines = new ArrayList<>();
-      lines.add("dn: " + Utilities.getRDNString("ds-cfg-attribute", attributeName) + ",cn=Index," + dn);
-      lines.add("objectClass: ds-cfg-local-db-index");
-      lines.add("objectClass: top");
-      lines.add("ds-cfg-attribute: " + attributeName);
-      lines.add("ds-cfg-index-entry-limit: " + entryLimitValue);
-      for (IndexTypeDescriptor type : indexTypes)
+      final ManagementContext mCtx = LDAPManagementContext.createFromContext(JNDIDirContextAdaptor.adapt(ctx));
+      final BackendCfgClient backend = mCtx.getRootConfiguration().getBackend(backendName.getText());
+      if (backend instanceof LocalDBBackendCfgClient)
       {
-        lines.add("ds-cfg-index-type: " + type.toLocalDBIndexType());
+        createLocalDBIndexOnline((LocalDBBackendCfgClient) backend);
+        return;
       }
-      StringBuilder sb = new StringBuilder();
-      for (String line : lines)
-      {
-        sb.append(line).append(ServerConstants.EOL);
-      }
-      return sb.toString();
+      createBackendIndexOnline((PluggableBackendCfgClient) backend);
     }
 
-    private void createIndex() throws OpenDsException
+    private void createBackendIndexOnline(final PluggableBackendCfgClient backend) throws OpenDsException
     {
-      LDIFImportConfig ldifImportConfig = null;
-      try
+      final List<PropertyException> exceptions = new ArrayList<>();
+      final BackendIndexCfgClient index = backend.createBackendIndex(
+          BackendIndexCfgDefn.getInstance(), attributeName, exceptions);
+      index.setIndexType(IndexTypeDescriptor.toBackendIndexTypes(indexTypes));
+      if (entryLimitValue != index.getIndexEntryLimit())
       {
-        String ldif = getIndexLDIF();
-
-        ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
-        LDIFReader reader = new LDIFReader(ldifImportConfig);
-        Entry backendConfigEntry;
-        while ((backendConfigEntry = reader.readEntry()) != null)
-        {
-          DirectoryServer.getConfigHandler().addEntry(backendConfigEntry, null);
-        }
-        DirectoryServer.getConfigHandler().writeUpdatedConfig();
+        index.setIndexEntryLimit(entryLimitValue);
       }
-      catch (IOException ioe)
-      {
-        throw new OfflineUpdateException(ERR_CTRL_PANEL_ERROR_UPDATING_CONFIGURATION.get(ioe), ioe);
-      }
-      finally
-      {
-        if (ldifImportConfig != null)
-        {
-          ldifImportConfig.close();
-        }
-      }
+      index.commit();
+      Utilities.throwFirstFrom(exceptions);
     }
 
-    private void createIndex(final InitialLdapContext ctx) throws OpenDsException
+    @RemoveOnceLocalDBBackendIsPluggable
+    private void createLocalDBIndexOnline(final LocalDBBackendCfgClient backend) throws OpenDsException
     {
-      // Instead of adding indexes using management framework, use this approach
-      // so that we have to define the additional indexes only in the method
-      // getBackendLdif.
-      String ldif = getIndexLDIF();
-      LDIFImportConfig ldifImportConfig = null;
-      try
+      final List<PropertyException> exceptions = new ArrayList<>();
+      final LocalDBIndexCfgClient index = backend.createLocalDBIndex(
+          LocalDBIndexCfgDefn.getInstance(), backendName.getText(), exceptions);
+      index.setIndexType(IndexTypeDescriptor.toLocalDBIndexTypes(indexTypes));
+      if (entryLimitValue != index.getIndexEntryLimit())
       {
-        ldifImportConfig = new LDIFImportConfig(new StringReader(ldif));
-        LDIFReader reader = new LDIFReader(ldifImportConfig);
-        Entry indexEntry = reader.readEntry();
-        Attributes attrs = new BasicAttributes();
-
-        BasicAttribute oc = new BasicAttribute("objectClass");
-        for (ByteString bs : indexEntry.getObjectClassAttribute())
-        {
-          oc.add(bs.toString());
-        }
-        attrs.put(oc);
-
-        List<Attribute> odsAttrs = indexEntry.getAttributes();
-        for (Attribute odsAttr : odsAttrs)
-        {
-          String attrName = odsAttr.getName();
-          BasicAttribute attr = new BasicAttribute(attrName);
-          for (ByteString bs : odsAttr)
-          {
-            attr.add(bs.toString());
-          }
-          attrs.put(attr);
-        }
-
-        final StringBuilder sb = new StringBuilder();
-        sb.append(getConfigCommandLineName());
-        Collection<String> args = getObfuscatedCommandLineArguments(getDSConfigCommandLineArguments());
-        for (String arg : args)
-        {
-          sb.append(" ").append(CommandBuilder.escapeValue(arg));
-        }
-
-        ctx.createSubcontext(indexEntry.getName().toString(), attrs);
+        index.setIndexEntryLimit(entryLimitValue);
       }
-      catch (Throwable t)
-      {
-        throw new OnlineUpdateException(ERR_CTRL_PANEL_ERROR_UPDATING_CONFIGURATION.get(t), t);
-      }
-      finally
-      {
-        if (ldifImportConfig != null)
-        {
-          ldifImportConfig.close();
-        }
-      }
+      index.commit();
+      Utilities.throwFirstFrom(exceptions);
     }
 
     @Override
diff --git a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java
index bd9fd06..3a5e079 100644
--- a/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java
+++ b/opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/util/Utilities.java
@@ -2891,4 +2891,23 @@
     return null;
   }
 
+  /**
+   * Throw the first exception of the list (if any).
+   *
+   * @param <E>
+   *          The exception type
+   * @param exceptions
+   *          A list of exceptions.
+   * @throws E
+   *           The first element of the provided list (if the list is not
+   *           empty).
+   */
+  public static <E extends Exception> void throwFirstFrom(List<? extends E> exceptions) throws E
+  {
+    if (!exceptions.isEmpty())
+    {
+      throw exceptions.get(0);
+    }
+  }
+
 }

--
Gitblit v1.10.0