From 2cb6f13fd6884330d7c33cc79cf2dd74ec88fc4c Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Mon, 19 Oct 2009 18:30:34 +0000
Subject: [PATCH] Fix for issue 4284 (Add ability to Duplicate an existing entry with the Control Panel).

---
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/GenericDialog.java       |    3 
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java  |   71 +++++
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java  |   37 ++
 opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/DuplicateEntryPanel.java |  544 +++++++++++++++++++++++++++++++++++++++++++++
 opendj-sdk/opends/src/messages/messages/admin_tool.properties                               |   25 ++
 5 files changed, 667 insertions(+), 13 deletions(-)

diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
index 737fa52..3464d05 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
@@ -113,6 +113,7 @@
   private JMenuItem popupNewOrganizationMenuItem;
   private JMenuItem popupNewDomainMenuItem;
   private JMenuItem popupResetUserPasswordMenuItem;
+  private JMenuItem popupDuplicateEntryMenuItem;
 
   private LDAPEntryPanel entryPane;
 
@@ -143,6 +144,9 @@
   private GenericDialog newEntryFromLDIFDlg;
   private NewEntryFromLDIFPanel newEntryFromLDIFPanel;
 
+  private GenericDialog duplicateEntryDlg;
+  private DuplicateEntryPanel duplicateEntryPanel;
+
   private boolean ignoreTreeSelectionEvents = false;
 
   private ArrayList<LDAPEntryReader> entryReaderQueue =
@@ -297,10 +301,14 @@
         popupDeleteMenuItem.setEnabled(enableDelete);
         menuBar.deleteMenuItem.setEnabled(enableDelete);
 
-        boolean enableCopyDN = (paths != null) && (paths.length > 0);
+        boolean enableCopyDN = path != null;
         popupCopyDNMenuItem.setEnabled(enableCopyDN);
         menuBar.copyDNMenuItem.setEnabled(enableCopyDN);
 
+        boolean enableDuplicateEntry = enableCopyDN;
+        popupDuplicateEntryMenuItem.setEnabled(enableDuplicateEntry);
+        menuBar.duplicateEntryMenuItem.setEnabled(enableDuplicateEntry);
+
         boolean enableAddToGroup = enableCopyDN;
         popupAddToGroupMenuItem.setEnabled(enableAddToGroup);
         menuBar.addToGroupMenuItem.setEnabled(enableAddToGroup);
@@ -696,6 +704,22 @@
     popup.add(popupAddToGroupMenuItem);
     popupAddToGroupMenuItem.setEnabled(false);
 
+    popup.add(new JSeparator());
+
+    popupDuplicateEntryMenuItem = Utilities.createMenuItem(
+        INFO_CTRL_PANEL_DUPLICATE_ENTRY_MENU.get());
+    popupDuplicateEntryMenuItem.addActionListener(new ActionListener()
+    {
+      /**
+       * {@inheritDoc}
+       */
+      public void actionPerformed(ActionEvent ev)
+      {
+        duplicateEntry();
+      }
+    });
+    popup.add(popupDuplicateEntryMenuItem);
+
     popupCopyDNMenuItem = Utilities.createMenuItem(
         INFO_CTRL_PANEL_COPY_DN_MENU.get());
     popupCopyDNMenuItem.addActionListener(new ActionListener()
@@ -708,9 +732,9 @@
         copyDN();
       }
     });
-    popup.add(new JSeparator());
     popup.add(popupCopyDNMenuItem);
     popupCopyDNMenuItem.setEnabled(false);
+
     popup.add(new JSeparator());
 
     popupDeleteMenuItem = Utilities.createMenuItem(
@@ -912,6 +936,32 @@
     newEntryFromLDIFDlg.setVisible(true);
   }
 
+  private void duplicateEntry()
+  {
+    duplicateEntryDlg = null;
+    if (duplicateEntryDlg == null)
+    {
+      if (duplicateEntryPanel == null)
+      {
+        duplicateEntryPanel = new DuplicateEntryPanel();
+        duplicateEntryPanel.setInfo(getInfo());
+      }
+      duplicateEntryDlg = new GenericDialog(Utilities.getFrame(this),
+          duplicateEntryPanel);
+      Utilities.centerGoldenMean(duplicateEntryDlg,
+          Utilities.getParentDialog(this));
+    }
+    TreePath[] paths = treePane.getTree().getSelectionPaths();
+    BasicNode node = null;
+    if ((paths != null) && (paths.length == 1))
+    {
+      TreePath path = paths[0];
+      node = (BasicNode)path.getLastPathComponent();
+    }
+    duplicateEntryPanel.setEntryToDuplicate(node, controller);
+    duplicateEntryDlg.setVisible(true);
+  }
+
   private void deleteClicked()
   {
     ArrayList<Message> errors = new ArrayList<Message>();
@@ -1043,6 +1093,7 @@
     JMenuItem newOrganizationMenuItem;
     JMenuItem newDomainMenuItem;
     JMenuItem newEntryFromLDIFMenuItem;
+    JMenuItem duplicateEntryMenuItem;
 
     /**
      * Constructor.
@@ -1350,6 +1401,22 @@
       menu.add(addToGroupMenuItem);
 
       menu.add(new JSeparator());
+
+      duplicateEntryMenuItem = Utilities.createMenuItem(
+          INFO_CTRL_PANEL_DUPLICATE_ENTRY_MENU.get());
+      duplicateEntryMenuItem.addActionListener(new ActionListener()
+      {
+        /**
+         * {@inheritDoc}
+         */
+        public void actionPerformed(ActionEvent ev)
+        {
+          duplicateEntry();
+        }
+      });
+      duplicateEntryMenuItem.setEnabled(false);
+      menu.add(duplicateEntryMenuItem);
+
       copyDNMenuItem = Utilities.createMenuItem(
           INFO_CTRL_PANEL_COPY_DN_MENU.get());
       copyDNMenuItem.addActionListener(new ActionListener()
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/DuplicateEntryPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/DuplicateEntryPanel.java
new file mode 100644
index 0000000..c593864
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/DuplicateEntryPanel.java
@@ -0,0 +1,544 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Copyright 2009 Sun Microsystems, Inc.
+ */
+
+package org.opends.guitools.controlpanel.ui;
+
+import static org.opends.messages.AdminToolMessages.*;
+
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Set;
+
+import javax.naming.ldap.InitialLdapContext;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JTextField;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import org.opends.guitools.controlpanel.browser.BrowserController;
+import org.opends.guitools.controlpanel.datamodel.CustomSearchResult;
+import org.opends.guitools.controlpanel.ui.nodes.BasicNode;
+import org.opends.guitools.controlpanel.util.BackgroundTask;
+import org.opends.guitools.controlpanel.util.LDAPEntryReader;
+import org.opends.guitools.controlpanel.util.Utilities;
+import org.opends.messages.Message;
+import org.opends.quicksetup.util.Utils;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.util.Base64;
+import org.opends.server.util.LDIFException;
+import org.opends.server.util.ServerConstants;
+
+/**
+ * The panel used to duplicate an entry.
+ *
+ */
+public class DuplicateEntryPanel extends AbstractNewEntryPanel
+{
+  private static final long serialVersionUID = -9879879123123123L;
+  private JLabel lName;
+  private JTextField name;
+  private JLabel lParentDN;
+  private JTextField parentDN;
+  private JButton browse;
+  private JLabel dn;
+
+  private GenericDialog browseDlg;
+  private LDAPEntrySelectionPanel browsePanel;
+
+  private CustomSearchResult entryToDuplicate;
+  private String rdnAttribute;
+
+  private JLabel entryHasPasswordWarning;
+
+  private final static String DEFAULT_PASSWORD_VALUE = "password";
+
+  /**
+   * Default constructor.
+   *
+   */
+  public DuplicateEntryPanel()
+  {
+    super();
+    createLayout();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Component getPreferredFocusComponent()
+  {
+    return name;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean requiresScroll()
+  {
+    return true;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void setParent(BasicNode parentNode, BrowserController controller)
+  {
+    throw new IllegalArgumentException("this method must not be called");
+  }
+
+  /**
+   * Sets the entry to be duplicated.
+   * @param node the node to be duplicated.
+   * @param controller the browser controller.
+   */
+  public void setEntryToDuplicate(BasicNode node,
+      BrowserController controller)
+  {
+    if (node == null)
+    {
+      throw new IllegalArgumentException("node is null.");
+    }
+
+    displayMessage(INFO_CTRL_PANEL_READING_SUMMARY.get());
+    setEnabledOK(false);
+
+    entryToDuplicate = null;
+    super.controller = controller;
+
+    DN parentDN;
+    String rdn;
+    try
+    {
+      DN nodeDN = DN.decode(node.getDN());
+      if (nodeDN.isNullDN())
+      {
+        parentDN = nodeDN;
+        rdn = "(1)";
+      }
+      else
+      {
+        parentDN = nodeDN.getParent();
+        rdn = nodeDN.getRDN().getAttributeValue(0).toString()+"-1";
+      }
+    }
+    catch (DirectoryException de)
+    {
+      throw new IllegalStateException("Unexpected error decoding dn: '"+
+          node.getDN()+"' error: "+de, de);
+    }
+    this.parentDN.setText(parentDN.toString());
+    this.name.setText(rdn);
+
+    readEntry(node);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected Message getProgressDialogTitle()
+  {
+    return INFO_CTRL_PANEL_DUPLICATE_ENTRY_TITLE.get();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Message getTitle()
+  {
+    return INFO_CTRL_PANEL_DUPLICATE_ENTRY_TITLE.get();
+  }
+
+  /**
+   * Creates the layout of the panel (but the contents are not populated here).
+   */
+  private void createLayout()
+  {
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.gridx = 0;
+    gbc.gridy = 0;
+
+    addErrorPane(gbc);
+
+    gbc.gridy ++;
+    gbc.gridwidth = 1;
+    gbc.weightx = 0.0;
+    gbc.weighty = 0.0;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+
+    gbc.gridx = 0;
+    gbc.insets.left = 0;
+    lName = Utilities.createPrimaryLabel(
+        INFO_CTRL_PANEL_DUPLICATE_ENTRY_NAME_LABEL.get());
+    add(lName, gbc);
+    name = Utilities.createTextField("", 30);
+    gbc.weightx = 1.0;
+    gbc.gridwidth = 2;
+    gbc.weightx = 1.0;
+    gbc.insets.left = 10;
+    gbc.gridx = 1;
+    add(name, gbc);
+
+    gbc.gridy ++;
+    gbc.gridx = 0;
+    gbc.insets.top = 10;
+    gbc.insets.left = 0;
+    gbc.gridwidth = 1;
+    gbc.weightx = 0.0;
+
+    gbc.fill = GridBagConstraints.BOTH;
+    lParentDN = Utilities.createPrimaryLabel(
+        INFO_CTRL_PANEL_DUPLICATE_ENTRY_PARENT_DN_LABEL.get());
+    add(lParentDN, gbc);
+
+    parentDN = Utilities.createTextField("", 30);
+    gbc.weightx = 1.0;
+    gbc.weightx = 1.0;
+    gbc.insets.left = 10;
+    gbc.gridx = 1;
+    add(parentDN, gbc);
+
+    browse = Utilities.createButton(
+        INFO_CTRL_PANEL_BROWSE_BUTTON_LABEL.get());
+    gbc.weightx = 0.0;
+    gbc.gridx = 2;
+    add(browse, gbc);
+    browse.addActionListener(new ActionListener()
+    {
+      /**
+       * {@inheritDoc}
+       */
+      public void actionPerformed(ActionEvent ev)
+      {
+        browseClicked();
+      }
+    });
+
+    gbc.gridx = 0;
+    gbc.gridy ++;
+    gbc.insets.left = 0;
+    Message msg = INFO_CTRL_PANEL_ENTRY_TO_DUPLICATE_HAS_PASSWORD_WARNING.get(
+        DEFAULT_PASSWORD_VALUE);
+    entryHasPasswordWarning = Utilities.createDefaultLabel();
+    Utilities.setWarningLabel(entryHasPasswordWarning, msg);
+    gbc.gridwidth = 3;
+    add(entryHasPasswordWarning, gbc);
+
+    gbc.gridwidth = 1;
+    gbc.gridx = 0;
+    gbc.gridy ++;
+    gbc.insets.left = 0;
+    add(Utilities.createPrimaryLabel(INFO_CTRL_PANEL_DUPLICATE_ENTRY_DN.get()),
+        gbc);
+    dn = Utilities.createDefaultLabel();
+
+    gbc.gridx = 1;
+    gbc.gridwidth = 2;
+    gbc.insets.left = 10;
+    add(dn, gbc);
+
+    DocumentListener listener = new DocumentListener()
+    {
+      /**
+       * {@inheritDoc}
+       */
+      public void insertUpdate(DocumentEvent ev)
+      {
+        updateDNValue();
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public void changedUpdate(DocumentEvent ev)
+      {
+        insertUpdate(ev);
+      }
+
+      /**
+       * {@inheritDoc}
+       */
+      public void removeUpdate(DocumentEvent ev)
+      {
+        insertUpdate(ev);
+      }
+    };
+    name.getDocument().addDocumentListener(listener);
+    parentDN.getDocument().addDocumentListener(listener);
+
+    addBottomGlue(gbc);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected void checkSyntax(ArrayList<Message> errors)
+  {
+    int origSize = errors.size();
+    String name = this.name.getText().trim();
+    setPrimaryValid(lName);
+    setPrimaryValid(lParentDN);
+    if (name.length() == 0)
+    {
+      errors.add(ERR_CTRL_PANEL_DUPLICATE_ENTRY_NAME_EMPTY.get());
+      setPrimaryInvalid(lName);
+    }
+    String parentDN = this.parentDN.getText().trim();
+    if (!Utils.isDn(parentDN))
+    {
+      errors.add(ERR_CTRL_PANEL_DUPLICATE_ENTRY_PARENT_DN_NOT_VALID.get());
+      setPrimaryInvalid(lParentDN);
+    }
+    else if (!entryExists(parentDN))
+    {
+      errors.add(ERR_CTRL_PANEL_DUPLICATE_ENTRY_PARENT_DOES_NOT_EXIST.get());
+      setPrimaryInvalid(lParentDN);
+    }
+
+    if (errors.size() == origSize)
+    {
+      try
+      {
+        getEntry();
+      }
+      catch (IOException ioe)
+      {
+        errors.add(ERR_CTRL_PANEL_ERROR_CHECKING_ENTRY.get(ioe.toString()));
+      }
+      catch (LDIFException le)
+      {
+        errors.add(le.getMessageObject());
+      }
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected String getLDIF()
+  {
+    String dn = this.dn.getText();
+    StringBuilder sb = new StringBuilder();
+    sb.append("dn: "+dn);
+    for (String attrName : entryToDuplicate.getAttributeNames())
+    {
+      Set<Object> values = entryToDuplicate.getAttributeValues(attrName);
+      if (attrName.equalsIgnoreCase(ServerConstants.ATTR_USER_PASSWORD))
+      {
+        sb.append("\n");
+        sb.append(attrName+": "+DEFAULT_PASSWORD_VALUE);
+      }
+      else if (!attrName.equalsIgnoreCase(rdnAttribute))
+      {
+        if (!ViewEntryPanel.isEditable(attrName,
+            getInfo().getServerDescriptor().getSchema()))
+        {
+          continue;
+        }
+        for (Object value : values)
+        {
+          sb.append("\n");
+          if (value instanceof String)
+          {
+            sb.append(attrName+": "+value);
+          }
+          else if (value instanceof byte[])
+          {
+            sb.append(attrName+":: "+Base64.encode((byte[])value));
+          }
+          else
+          {
+            sb.append(attrName+": "+value);
+          }
+        }
+      }
+      else
+      {
+        String newValue = null;
+        try
+        {
+          DN theDN = DN.decode(dn);
+          newValue = theDN.getRDN().getAttributeValue(0).toString();
+        }
+        catch (DirectoryException de)
+        {
+          throw new IllegalStateException("Unexpected error with dn: '"+dn+
+              "' "+de, de);
+        }
+        if (values.size() == 1)
+        {
+          sb.append("\n");
+          sb.append(attrName+": "+newValue);
+        }
+        else
+        {
+          String oldValue = null;
+          try
+          {
+            DN oldDN = DN.decode(entryToDuplicate.getDN());
+            oldValue = oldDN.getRDN().getAttributeValue(0).toString();
+          }
+          catch (DirectoryException de)
+          {
+            throw new IllegalStateException("Unexpected error with dn: '"+
+                entryToDuplicate.getDN()+"' "+de, de);
+          }
+          for (Object value : values)
+          {
+            sb.append("\n");
+            if (oldValue.equals(value))
+            {
+              sb.append(attrName+": "+newValue);
+            }
+            else
+            {
+              sb.append(attrName+": "+value);
+            }
+          }
+        }
+      }
+    }
+    return sb.toString();
+  }
+
+  private void browseClicked()
+  {
+    if (browseDlg == null)
+    {
+      browsePanel = new LDAPEntrySelectionPanel();
+      browsePanel.setTitle(INFO_CTRL_PANEL_CHOOSE_PARENT_ENTRY_DN.get());
+      browsePanel.setFilter(
+          LDAPEntrySelectionPanel.Filter.DEFAULT);
+      browsePanel.setMultipleSelection(false);
+      browsePanel.setInfo(getInfo());
+      browseDlg = new GenericDialog(Utilities.getFrame(this),
+          browsePanel);
+      Utilities.centerGoldenMean(browseDlg,
+          Utilities.getParentDialog(this));
+      browseDlg.setModal(true);
+    }
+    browseDlg.setVisible(true);
+    String[] dns = browsePanel.getDNs();
+    if (dns.length > 0)
+    {
+      for (String dn : dns)
+      {
+        parentDN.setText(dn);
+      }
+    }
+  }
+
+  private void readEntry(final BasicNode node)
+  {
+    final long t1 = System.currentTimeMillis();
+    BackgroundTask<CustomSearchResult> task =
+      new BackgroundTask<CustomSearchResult>()
+    {
+      public CustomSearchResult processBackgroundTask() throws Throwable
+      {
+        InitialLdapContext ctx =
+          controller.findConnectionForDisplayedEntry(node);
+        LDAPEntryReader reader = new LDAPEntryReader(node.getDN(), ctx);
+        sleepIfRequired(700, t1);
+        return reader.processBackgroundTask();
+      }
+
+      public void backgroundTaskCompleted(CustomSearchResult sr,
+          Throwable throwable)
+      {
+        if (throwable != null)
+        {
+          Message title = INFO_CTRL_PANEL_ERROR_SEARCHING_ENTRY_TITLE.get();
+          Message details =
+            ERR_CTRL_PANEL_ERROR_SEARCHING_ENTRY.get(node.getDN(),
+                throwable.toString());
+          displayErrorMessage(title, details);
+        }
+        else
+        {
+          entryToDuplicate = sr;
+          try
+          {
+            DN dn = DN.decode(sr.getDN());
+            rdnAttribute = dn.getRDN().getAttributeType(0).getNameOrOID();
+
+            updateDNValue();
+            entryHasPasswordWarning.setVisible(hasPassword());
+            displayMainPanel();
+            setEnabledOK(true);
+          }
+          catch (DirectoryException de)
+          {
+            displayErrorMessage(INFO_CTRL_PANEL_ERROR_DIALOG_TITLE.get(),
+                de.getMessageObject());
+          }
+        }
+      }
+    };
+    task.startBackgroundTask();
+  }
+
+  private void updateDNValue()
+  {
+    String value = name.getText().trim();
+    if (value.length() > 0)
+    {
+       String rdn = Utilities.getRDNString(rdnAttribute, value);
+          dn.setText(rdn+","+parentDN.getText().trim());
+    }
+    else
+    {
+      dn.setText(","+parentDN.getText().trim());
+    }
+  }
+
+  private boolean hasPassword()
+  {
+    return !entryToDuplicate.getAttributeValues(
+        ServerConstants.ATTR_USER_PASSWORD).isEmpty();
+  }
+
+  private void sleepIfRequired(long sleepTime, long startTime)
+  {
+    long tSleep = sleepTime - (System.currentTimeMillis() - startTime);
+    if (tSleep > 0)
+    {
+      try
+      {
+        Thread.sleep(tSleep);
+      }
+      catch (Throwable t)
+      {
+      }
+    }
+  }
+}
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/GenericDialog.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/GenericDialog.java
index aaccfdf..6f35209 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/GenericDialog.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/GenericDialog.java
@@ -238,7 +238,8 @@
     {
       lastComponentWithFocus = panel.getPreferredFocusComponent();
     }
-    if (visible && (lastComponentWithFocus != null))
+    if (visible && (lastComponentWithFocus != null) &&
+        lastComponentWithFocus.isVisible())
     {
       lastComponentWithFocus.requestFocusInWindow();
     }
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
index 15dc214..07a08e9 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
@@ -29,6 +29,7 @@
 
 import static org.opends.messages.AdminToolMessages.*;
 
+import java.awt.CardLayout;
 import java.awt.Color;
 import java.awt.Component;
 import java.awt.Container;
@@ -109,6 +110,8 @@
 public abstract class StatusGenericPanel extends JPanel
 implements ConfigChangeListener
 {
+  private static final long serialVersionUID = -9123358652232556732L;
+
   /**
    * The string to be used as combo separator.
    */
@@ -131,9 +134,15 @@
 
   private boolean disposeOnClose = false;
 
+  private JPanel cardPanel;
   private JPanel mainPanel;
   private JEditorPane message;
 
+  private CardLayout cardLayout;
+
+  private static final String MAIN_PANEL = "mainPanel";
+  private static final String MESSAGE_PANEL = "messagePanel";
+
   /**
    * The error pane.
    */
@@ -240,6 +249,10 @@
     super(new GridBagLayout());
     setBackground(ColorAndFontConstants.background);
 
+    cardLayout = new CardLayout();
+    cardPanel = new JPanel(cardLayout);
+    cardPanel.setOpaque(false);
+
     mainPanel = new JPanel(new GridBagLayout());
     mainPanel.setOpaque(false);
 
@@ -251,11 +264,18 @@
     gbc.fill = GridBagConstraints.BOTH;
     gbc.weightx = 1.0;
     gbc.weighty = 1.0;
-    super.add(mainPanel, gbc);
+    super.add(cardPanel, gbc);
+
+    cardPanel.add(mainPanel, MAIN_PANEL);
+
+    JPanel messagePanel = new JPanel(new GridBagLayout());
+    messagePanel.setOpaque(false);
     gbc.fill = GridBagConstraints.NONE;
     gbc.anchor = GridBagConstraints.CENTER;
-    super.add(message, gbc);
-    message.setVisible(false);
+    messagePanel.add(message, gbc);
+    cardPanel.add(messagePanel, MESSAGE_PANEL);
+
+    cardLayout.show(cardPanel, MAIN_PANEL);
   }
 
   /**
@@ -640,7 +660,7 @@
     }
     else
     {
-      if (isLocal() || true)
+      if (isLocal())
       {
         rebuildIndexes = Utilities.displayConfirmationDialog(progressDialog,
             INFO_CTRL_PANEL_INDEX_REBUILD_REQUIRED_SUMMARY.get(),
@@ -1091,8 +1111,7 @@
    */
   protected void displayMainPanel()
   {
-    mainPanel.setVisible(true);
-    message.setVisible(false);
+    cardLayout.show(cardPanel, MAIN_PANEL);
   }
 
   /**
@@ -1112,8 +1131,7 @@
   {
     message.setText(Utilities.applyFont(msg.toString(),
         ColorAndFontConstants.progressFont));
-    mainPanel.setVisible(false);
-    message.setVisible(true);
+    cardLayout.show(cardPanel, MESSAGE_PANEL);
   }
 
   /**
@@ -1125,8 +1143,7 @@
   {
     updateErrorPane(message, title, ColorAndFontConstants.errorTitleFont,
         msg, ColorAndFontConstants.defaultFont);
-    mainPanel.setVisible(false);
-    message.setVisible(true);
+    cardLayout.show(cardPanel, MESSAGE_PANEL);
   }
 
   /**
diff --git a/opendj-sdk/opends/src/messages/messages/admin_tool.properties b/opendj-sdk/opends/src/messages/messages/admin_tool.properties
index 20d999a..bfb7558 100644
--- a/opendj-sdk/opends/src/messages/messages/admin_tool.properties
+++ b/opendj-sdk/opends/src/messages/messages/admin_tool.properties
@@ -232,12 +232,20 @@
 INFO_NOT_AVAILABLE_AUTHENTICATION_REQUIRED_CLI_LEGEND=* Information only \
  available if you provide valid authentication information when launching the \
  status command.
+#
+# Note that the following property contains line breaks in HTML format (<br>)
+# and a <html> tag.
+#
 INFO_NOT_AVAILABLE_AUTHENTICATION_REQUIRED_TOOLTIP=<html>Information is only \
  available if you are authenticated<br>as an administrative user.
 INFO_NOT_AVAILABLE_SERVER_DOWN_CLI_LABEL=<not available> (*)
 INFO_NOT_AVAILABLE_SERVER_DOWN_CLI_LEGEND=* Information only available if \
  server is running and you provide valid authentication information when \
  launching the status command.
+#
+# Note that the following property contains line breaks in HTML format (<br>)
+# and a <html> tag.
+#
 INFO_NOT_AVAILABLE_SERVER_DOWN_TOOLTIP=<html>Information is only available if \
  server is running and you are authenticated<br>as an administrative user.
 INFO_NOTHING_SELECTED_TO_UNINSTALL=You must select something to be \
@@ -2148,6 +2156,9 @@
 INFO_CTRL_PANEL_LDIF_SYNTAX_LABEL=Enter LDIF syntax for the new entry:
 INFO_CTRL_PANEL_CHECK_SYNTAX_BUTTON=Check Syntax
 
+INFO_CTRL_PANEL_DUPLICATE_ENTRY_TITLE=Duplicate Entry
+INFO_CTRL_PANEL_DUPLICATE_ENTRY_MENU=Duplicate Entry...
+
 INFO_CTRL_PANEL_NEW_GROUP_PANEL_TITLE=New Group
 MILD_ERR_CTRL_PANEL_NAME_OF_GROUP_REQUIRED=You must provide a value for the \
  name of the group.
@@ -2833,3 +2844,17 @@
 INFO_CTRL_PANEL_MULTIPLE_TASKS_SELECTED=-Multiple Tasks Selected-
 INFO_CTRL_PANEL_NO_TASK_SPECIFIC_DETAILS=-No Task Specific Details-
 INFO_OPERATION_START_TIME_MESSAGE=Operation date: %s
+
+INFO_CTRL_PANEL_CHOOSE_PARENT_ENTRY_DN=Choose Parent DN
+INFO_CTRL_PANEL_DUPLICATE_ENTRY_NAME_LABEL=New Entry Name:
+INFO_CTRL_PANEL_DUPLICATE_ENTRY_PARENT_DN_LABEL=Parent Entry DN:
+MILD_ERR_CTRL_PANEL_DUPLICATE_ENTRY_NAME_EMPTY=You must provide the name of \
+ the new entry.
+MILD_ERR_CTRL_PANEL_DUPLICATE_ENTRY_PARENT_DN_NOT_VALID=You must provide a \
+ valid DN for the parent entry.
+MILD_ERR_CTRL_PANEL_DUPLICATE_ENTRY_PARENT_DOES_NOT_EXIST=The parent entry \
+ does not exist.
+INFO_CTRL_PANEL_DUPLICATE_ENTRY_DN=Entry DN:
+INFO_CTRL_PANEL_ENTRY_TO_DUPLICATE_HAS_PASSWORD_WARNING=The duplicated entry \
+ will contain a password with value '%s'
+

--
Gitblit v1.10.0