001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008-2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2011-2015 ForgeRock AS
026 */
027
028package org.opends.guitools.controlpanel.ui;
029
030import static org.opends.messages.AdminToolMessages.*;
031import static org.opends.messages.QuickSetupMessages.*;
032
033import java.awt.Component;
034import java.awt.GridBagConstraints;
035import java.awt.GridBagLayout;
036import java.awt.event.ItemEvent;
037import java.awt.event.ItemListener;
038import java.io.File;
039import java.io.IOException;
040import java.util.ArrayList;
041import java.util.Collection;
042import java.util.Collections;
043import java.util.Enumeration;
044import java.util.HashSet;
045import java.util.LinkedHashSet;
046import java.util.LinkedList;
047import java.util.List;
048import java.util.Set;
049import java.util.SortedSet;
050import java.util.TreeSet;
051
052import javax.swing.AbstractButton;
053import javax.swing.Box;
054import javax.swing.ButtonGroup;
055import javax.swing.DefaultComboBoxModel;
056import javax.swing.JButton;
057import javax.swing.JComboBox;
058import javax.swing.JComponent;
059import javax.swing.JLabel;
060import javax.swing.JPanel;
061import javax.swing.JRadioButton;
062import javax.swing.JTextField;
063import javax.swing.SwingUtilities;
064import javax.swing.event.ChangeEvent;
065import javax.swing.event.ChangeListener;
066import javax.swing.event.DocumentEvent;
067import javax.swing.event.DocumentListener;
068
069import org.forgerock.i18n.LocalizableMessage;
070import org.forgerock.opendj.adapter.server3x.Converters;
071import org.forgerock.opendj.config.LDAPProfile;
072import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
073import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor;
074import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
075import org.opends.guitools.controlpanel.datamodel.IndexTypeDescriptor;
076import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
077import org.opends.guitools.controlpanel.event.BrowseActionListener;
078import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
079import org.opends.guitools.controlpanel.task.OfflineUpdateException;
080import org.opends.guitools.controlpanel.task.OnlineUpdateException;
081import org.opends.guitools.controlpanel.task.Task;
082import org.opends.guitools.controlpanel.ui.renderer.CustomListCellRenderer;
083import org.opends.guitools.controlpanel.util.ConfigReader;
084import org.opends.guitools.controlpanel.util.Utilities;
085import org.opends.quicksetup.Installation;
086import org.opends.quicksetup.installer.InstallerHelper;
087import org.opends.quicksetup.util.Utils;
088import org.opends.server.admin.AdminException;
089import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
090import org.opends.server.admin.client.ldap.LDAPManagementContext;
091import org.opends.server.admin.std.client.BackendCfgClient;
092import org.opends.server.admin.std.client.BackendIndexCfgClient;
093import org.opends.server.admin.std.client.LocalDBBackendCfgClient;
094import org.opends.server.admin.std.client.LocalDBIndexCfgClient;
095import org.opends.server.admin.std.client.PluggableBackendCfgClient;
096import org.opends.server.admin.std.client.RootCfgClient;
097import org.opends.server.admin.std.meta.BackendCfgDefn;
098import org.opends.server.admin.std.meta.BackendIndexCfgDefn;
099import org.opends.server.admin.std.meta.BackendIndexCfgDefn.IndexType;
100import org.opends.server.admin.std.meta.LocalDBIndexCfgDefn;
101import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable;
102import org.opends.server.core.DirectoryServer;
103import org.opends.server.extensions.ConfigFileHandler;
104import org.opends.server.tools.BackendCreationHelper;
105import org.opends.server.tools.BackendCreationHelper.DefaultIndex;
106import org.opends.server.tools.BackendTypeHelper;
107import org.opends.server.tools.BackendTypeHelper.BackendTypeUIAdapter;
108import org.opends.server.tools.ImportLDIF;
109import org.opends.server.tools.LDAPModify;
110import org.opends.server.tools.makeldif.MakeLDIF;
111import org.opends.server.types.DN;
112import org.opends.server.types.OpenDsException;
113import org.opends.server.util.RemoveOnceNewConfigFrameworkIsUsed;
114import org.opends.server.util.SetupUtils;
115
116import com.forgerock.opendj.cli.CommandBuilder;
117
118/**
119 * The class that appears when the user clicks on 'New Base DN'.
120 */
121public class NewBaseDNPanel extends StatusGenericPanel
122{
123  private static final int MAX_ENTRIES_NUMBER_GENERATED = 1000;
124  private static final int MAX_ENTRIES_NUMBER_GENERATED_LOCAL = 20000;
125  private static final long serialVersionUID = -2680821576362341119L;
126  private static final LocalizableMessage NEW_BACKEND_TEXT = INFO_CTRL_PANEL_NEW_BACKEND_LABEL.get();
127
128  private JComboBox<?> backends;
129  private JComboBox<BackendTypeUIAdapter> backendTypes;
130  private JTextField newBackend;
131  private JTextField baseDN;
132  private JRadioButton onlyCreateBaseEntry;
133  private JRadioButton leaveDatabaseEmpty;
134  private JRadioButton importDataFromLDIF;
135  private JRadioButton importAutomaticallyGenerated;
136  private JTextField path;
137  private JTextField numberOfEntries;
138  private JLabel lRemoteFileHelp;
139  private JButton browseImportPath;
140
141  private JLabel lBackend;
142  private JLabel lDirectoryBaseDN;
143  private JLabel lPath;
144  private JLabel lNumberOfEntries;
145  private JLabel lDirectoryData;
146  private JLabel lNewBackendType;
147
148  private DocumentListener documentListener;
149
150  /** Default constructor. */
151  public NewBaseDNPanel()
152  {
153    super();
154    createLayout();
155  }
156
157  /** {@inheritDoc} */
158  @Override
159  public LocalizableMessage getTitle()
160  {
161    return INFO_CTRL_PANEL_NEW_BASE_DN_TITLE.get();
162  }
163
164  /** {@inheritDoc} */
165  @Override
166  public Component getPreferredFocusComponent()
167  {
168    return baseDN;
169  }
170
171  /** {@inheritDoc} */
172  @Override
173  public void toBeDisplayed(boolean visible)
174  {
175    if (visible)
176    {
177      documentListener.changedUpdate(null);
178    }
179  }
180
181  /** Creates the layout of the panel (but the contents are not populated here). */
182  private void createLayout()
183  {
184    GridBagConstraints gbc = new GridBagConstraints();
185    addErrorPanel(gbc);
186    addBackendLabel(gbc);
187    addBackendNamesComboBox(gbc);
188    addNewBackendName(gbc);
189    addNewBackendTypeLabel(gbc);
190    addNewBackendTypeComboBox(gbc);
191    addBaseDNLabel(gbc);
192    addBaseDNTextField(gbc);
193    addBaseDNInlineHelp(gbc);
194    addDirectoryDataLabel(gbc);
195    addImportDataChoiceSection(gbc);
196    addBottomGlue(gbc);
197  }
198
199  private void addErrorPanel(GridBagConstraints gbc)
200  {
201    gbc.gridx = 0;
202    gbc.gridy = 0;
203    gbc.gridwidth = 3;
204    addErrorPane(gbc);
205  }
206
207  private void addBackendLabel(GridBagConstraints gbc)
208  {
209    gbc.anchor = GridBagConstraints.WEST;
210    gbc.weightx = 0.0;
211    gbc.gridwidth = 1;
212    gbc.gridy++;
213    gbc.fill = GridBagConstraints.NONE;
214    lBackend = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_BACKEND_LABEL.get());
215    add(lBackend, gbc);
216  }
217
218  @SuppressWarnings({ "unchecked", "rawtypes" })
219  private void addBackendNamesComboBox(GridBagConstraints gbc)
220  {
221    gbc.insets.left = 10;
222    gbc.gridx = 1;
223    backends = Utilities.createComboBox();
224    backends.setModel(new DefaultComboBoxModel(new Object[] { "bogus", NEW_BACKEND_TEXT }));
225    backends.setRenderer(new CustomListCellRenderer(backends));
226    backends.addItemListener(new IgnoreItemListener(backends));
227    gbc.gridwidth = 1;
228    add(backends, gbc);
229  }
230
231  private void addNewBackendTypeLabel(GridBagConstraints gbc)
232  {
233    gbc.insets.top = 10;
234    gbc.gridx = 0;
235    gbc.gridy++;
236    gbc.insets.left = 0;
237    gbc.gridwidth = 1;
238    lNewBackendType = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_BASE_DN_NEW_BACKEND_TYPE_LABEL.get());
239    add(lNewBackendType, gbc);
240    addBackendNameChangeListener(lNewBackendType);
241  }
242
243  @SuppressWarnings("unchecked")
244  private void addNewBackendTypeComboBox(GridBagConstraints gbc)
245  {
246    gbc.insets.left = 10;
247    gbc.gridx = 1;
248    gbc.gridwidth = 1;
249    final BackendTypeHelper backendTypeHelper = new BackendTypeHelper();
250    backendTypes = Utilities.createComboBox();
251    backendTypes.setModel(new DefaultComboBoxModel<>(backendTypeHelper.getBackendTypeUIAdaptors()));
252    backendTypes.setRenderer(new CustomListCellRenderer(backendTypes));
253    backendTypes.addItemListener(new IgnoreItemListener(backendTypes));
254    add(backendTypes, gbc);
255    addBackendNameChangeListener(backendTypes);
256  }
257
258  private void addNewBackendName(GridBagConstraints gbc)
259  {
260    gbc.gridx = 2;
261    newBackend = Utilities.createTextField();
262    newBackend.setColumns(18);
263    add(newBackend, gbc);
264    addBackendNameChangeListener(newBackend);
265  }
266
267  private void addBackendNameChangeListener(final JComponent component)
268  {
269    ItemListener comboListener = new ItemListener()
270    {
271      @Override
272      public void itemStateChanged(ItemEvent ev)
273      {
274        Object o = backends.getSelectedItem();
275        component.setVisible(NEW_BACKEND_TEXT.equals(o));
276      }
277    };
278    backends.addItemListener(comboListener);
279    comboListener.itemStateChanged(null);
280  }
281
282  private void addBaseDNLabel(GridBagConstraints gbc)
283  {
284    gbc.insets.top = 10;
285    gbc.gridx = 0;
286    gbc.gridy++;
287    gbc.insets.left = 0;
288    gbc.gridwidth = 1;
289    lDirectoryBaseDN = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_BASE_DN_LABEL.get());
290    add(lDirectoryBaseDN, gbc);
291  }
292
293  private void addBaseDNTextField(GridBagConstraints gbc)
294  {
295    gbc.gridx = 1;
296    gbc.insets.left = 10;
297    gbc.gridwidth = 2;
298    baseDN = Utilities.createTextField();
299    documentListener = new DocumentListener()
300    {
301      @Override
302      public void changedUpdate(DocumentEvent ev)
303      {
304        String text = baseDN.getText().trim();
305        setEnabledOK(text != null && text.length() > 0 && !errorPane.isVisible());
306      }
307
308      @Override
309      public void removeUpdate(DocumentEvent ev)
310      {
311        changedUpdate(ev);
312      }
313
314      @Override
315      public void insertUpdate(DocumentEvent ev)
316      {
317        changedUpdate(ev);
318      }
319    };
320    baseDN.getDocument().addDocumentListener(documentListener);
321    gbc.weightx = 1.0;
322    gbc.fill = GridBagConstraints.HORIZONTAL;
323    add(baseDN, gbc);
324  }
325
326  private void addBaseDNInlineHelp(GridBagConstraints gbc)
327  {
328    gbc.gridy++;
329    gbc.anchor = GridBagConstraints.EAST;
330    gbc.insets.top = 3;
331    JLabel inlineHelp = Utilities.createInlineHelpLabel(INFO_CTRL_PANEL_BASE_DN_EXAMPLE.get());
332    add(inlineHelp, gbc);
333  }
334
335  private void addDirectoryDataLabel(GridBagConstraints gbc)
336  {
337    gbc.gridx = 0;
338    gbc.gridy++;
339    gbc.insets.left = 0;
340    gbc.insets.top = 10;
341    gbc.gridwidth = 1;
342    gbc.weightx = 0.0;
343    lDirectoryData = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_DIRECTORY_DATA_LABEL.get());
344    add(lDirectoryData, gbc);
345  }
346
347  private void addImportDataChoiceSection(GridBagConstraints gbc)
348  {
349    onlyCreateBaseEntry = Utilities.createRadioButton(INFO_CTRL_PANEL_ONLY_CREATE_BASE_ENTRY_LABEL.get());
350    onlyCreateBaseEntry.setSelected(false);
351
352    gbc.insets.left = 10;
353    gbc.gridx = 1;
354    gbc.gridwidth = 2;
355    add(onlyCreateBaseEntry, gbc);
356
357    leaveDatabaseEmpty = Utilities.createRadioButton(INFO_CTRL_PANEL_LEAVE_DATABASE_EMPTY_LABEL.get());
358    leaveDatabaseEmpty.setSelected(false);
359
360    gbc.gridy++;
361    gbc.gridwidth = 2;
362    gbc.insets.top = 5;
363    add(leaveDatabaseEmpty, gbc);
364
365    importDataFromLDIF = Utilities.createRadioButton(INFO_CTRL_PANEL_IMPORT_FROM_LDIF_LABEL.get());
366    importDataFromLDIF.setSelected(false);
367
368    gbc.gridy++;
369    gbc.gridwidth = 2;
370    add(importDataFromLDIF, gbc);
371
372    gbc.gridy++;
373    gbc.gridwidth = 2;
374    gbc.insets.left = 30;
375    add(createPathPanel(), gbc);
376
377    importAutomaticallyGenerated =
378        Utilities.createRadioButton(INFO_CTRL_PANEL_IMPORT_AUTOMATICALLY_GENERATED_LABEL.get());
379    importAutomaticallyGenerated.setOpaque(false);
380    importAutomaticallyGenerated.setSelected(false);
381
382    gbc.gridy++;
383    gbc.gridwidth = 2;
384    gbc.insets.left = 10;
385    add(importAutomaticallyGenerated, gbc);
386
387    gbc.gridy++;
388    gbc.gridwidth = 2;
389    gbc.insets.left = 30;
390    add(createNumberOfUsersPanel(), gbc);
391
392    ButtonGroup group = new ButtonGroup();
393    group.add(onlyCreateBaseEntry);
394    group.add(leaveDatabaseEmpty);
395    group.add(importDataFromLDIF);
396    group.add(importAutomaticallyGenerated);
397
398    ChangeListener listener = new ChangeListener()
399    {
400      /** {@inheritDoc} */
401      @Override
402      public void stateChanged(ChangeEvent ev)
403      {
404        browseImportPath.setEnabled(importDataFromLDIF.isSelected());
405        lPath.setEnabled(importDataFromLDIF.isSelected());
406        lRemoteFileHelp.setEnabled(importDataFromLDIF.isSelected());
407        numberOfEntries.setEnabled(importAutomaticallyGenerated.isSelected());
408        lNumberOfEntries.setEnabled(importAutomaticallyGenerated.isSelected());
409      }
410    };
411
412    Enumeration<AbstractButton> buttons = group.getElements();
413    while (buttons.hasMoreElements())
414    {
415      buttons.nextElement().addChangeListener(listener);
416    }
417    onlyCreateBaseEntry.setSelected(true);
418    listener.stateChanged(null);
419  }
420
421  /** {@inheritDoc} */
422  @Override
423  public void configurationChanged(ConfigurationChangeEvent ev)
424  {
425    ServerDescriptor desc = ev.getNewDescriptor();
426    final SortedSet<String> sortedBackends = new TreeSet<>();
427    for (BackendDescriptor backend : desc.getBackends())
428    {
429      if (!backend.isConfigBackend())
430      {
431        sortedBackends.add(backend.getBackendID());
432      }
433    }
434
435    List<Object> newElements = new ArrayList<Object>(sortedBackends);
436    if (!sortedBackends.isEmpty())
437    {
438      newElements.add(COMBO_SEPARATOR);
439    }
440    newElements.add(NEW_BACKEND_TEXT);
441    super.updateComboBoxModel(newElements, (DefaultComboBoxModel<?>) backends.getModel());
442    updateErrorPaneAndOKButtonIfAuthRequired(desc,
443        isLocal() ? INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_FOR_CREATE_BASE_DN.get()
444                  : INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get(desc.getHostname()));
445    SwingUtilities.invokeLater(new Runnable()
446    {
447      @Override
448      public void run()
449      {
450        lRemoteFileHelp.setVisible(!isLocal());
451        browseImportPath.setVisible(isLocal());
452      }
453    });
454  }
455
456  private JPanel createPathPanel()
457  {
458    JPanel panel = new JPanel(new GridBagLayout());
459    panel.setOpaque(false);
460    GridBagConstraints gbc = new GridBagConstraints();
461    gbc.gridwidth = 1;
462    gbc.gridy = 0;
463    gbc.gridx = 0;
464    lPath = Utilities.createDefaultLabel(INFO_CTRL_PANEL_IMPORT_LDIF_PATH_LABEL.get());
465    panel.add(lPath, gbc);
466
467    gbc.gridx = 1;
468    gbc.insets.left = 10;
469    path = Utilities.createTextField();
470    gbc.weightx = 1.0;
471    gbc.fill = GridBagConstraints.HORIZONTAL;
472    panel.add(path, gbc);
473    browseImportPath = Utilities.createButton(INFO_CTRL_PANEL_BROWSE_BUTTON_LABEL.get());
474    browseImportPath.addActionListener(
475        new BrowseActionListener(path, BrowseActionListener.BrowseType.OPEN_LDIF_FILE, this));
476    gbc.gridx = 2;
477    gbc.weightx = 0.0;
478    panel.add(browseImportPath, gbc);
479
480    gbc.gridy++;
481    gbc.gridx = 1;
482    lRemoteFileHelp = Utilities.createInlineHelpLabel(INFO_CTRL_PANEL_REMOTE_SERVER_PATH.get());
483    gbc.insets.top = 3;
484    gbc.insets.left = 10;
485    panel.add(lRemoteFileHelp, gbc);
486
487    return panel;
488  }
489
490  private JPanel createNumberOfUsersPanel()
491  {
492    JPanel panel = new JPanel(new GridBagLayout());
493    panel.setOpaque(false);
494    GridBagConstraints gbc = new GridBagConstraints();
495    gbc.weightx = 0.0;
496    gbc.fill = GridBagConstraints.HORIZONTAL;
497    lNumberOfEntries = Utilities.createDefaultLabel(INFO_CTRL_PANEL_NUMBER_OF_USER_ENTRIES_LABEL.get());
498    panel.add(lNumberOfEntries, gbc);
499
500    gbc.gridx = 1;
501    gbc.insets.left = 10;
502    numberOfEntries = Utilities.createTextField("2000", 6);
503    panel.add(numberOfEntries, gbc);
504
505    gbc.gridx = 2;
506    gbc.insets.left = 0;
507    gbc.weightx = 1.0;
508    panel.add(Box.createHorizontalGlue(), gbc);
509
510    return panel;
511  }
512
513  /** {@inheritDoc} */
514  @Override
515  public void cancelClicked()
516  {
517    resetLabelAsValid();
518    super.cancelClicked();
519  }
520
521  private void resetLabelAsValid()
522  {
523    setPrimaryValid(lBackend);
524    setPrimaryValid(lDirectoryBaseDN);
525    setPrimaryValid(lDirectoryData);
526    setSecondaryValid(lPath);
527    setSecondaryValid(lNumberOfEntries);
528  }
529
530  /** {@inheritDoc} */
531  @Override
532  protected void checkOKButtonEnable()
533  {
534    documentListener.changedUpdate(null);
535  }
536
537  /** {@inheritDoc} */
538  @Override
539  public void okClicked()
540  {
541    resetLabelAsValid();
542
543    final Set<LocalizableMessage> errors = new LinkedHashSet<>();
544    final ServerDescriptor desc = getInfo().getServerDescriptor();
545    final Set<BackendDescriptor> existingBackends = desc.getBackends();
546
547    final String backendName = validateBackendName(existingBackends, errors);
548    final String dn = validateBaseDN(backendName, existingBackends, errors);
549    validateImportLDIFFilePath(errors);
550    validateAutomaticallyGenerated(errors);
551
552    if (errors.isEmpty())
553    {
554      final ProgressDialog progressDialog = new ProgressDialog(
555          Utilities.createFrame(), Utilities.getParentDialog(this), getTitle(), getInfo());
556      final NewBaseDNTask newTask = new NewBaseDNTask(getInfo(), progressDialog);
557      for (Task task : getInfo().getTasks())
558      {
559        task.canLaunch(newTask, errors);
560      }
561
562      if (errors.isEmpty())
563      {
564        launchOperation(newTask,
565            INFO_CTRL_PANEL_CREATING_BASE_DN_SUMMARY.get(dn),
566            INFO_CTRL_PANEL_CREATING_BASE_DN_COMPLETE.get(),
567            INFO_CTRL_PANEL_CREATING_BASE_DN_SUCCESSFUL.get(dn),
568            ERR_CTRL_PANEL_CREATING_BASE_DN_ERROR_SUMMARY.get(dn),
569            null,
570            ERR_CTRL_PANEL_CREATING_BASE_DN_ERROR_DETAILS,
571            progressDialog);
572        progressDialog.setVisible(true);
573        baseDN.setText("");
574        baseDN.grabFocus();
575        Utilities.getParentDialog(this).setVisible(false);
576      }
577    }
578
579    if (!errors.isEmpty())
580    {
581      displayErrorDialog(errors);
582    }
583  }
584
585  /** Returns the existing or the new backend name, once user have clicked on 'OK' button. */
586  private String validateBackendName(
587      final Set<BackendDescriptor> existingBackends, final Set<LocalizableMessage> errors)
588  {
589    final Object selectedItem = backends.getSelectedItem();
590    if (!selectedItem.equals(NEW_BACKEND_TEXT))
591    {
592      return selectedItem.toString();
593    }
594
595    final String backendName = newBackend.getText().trim();
596    if (backendName.length() == 0)
597    {
598      errors.add(ERR_NEW_BACKEND_NAME_REQUIRED.get());
599      setPrimaryInvalid(lBackend);
600      return backendName;
601    }
602
603    // Check that the backend is not already defined.
604    for (BackendDescriptor backend : existingBackends)
605    {
606      if (backendName.equalsIgnoreCase(backend.getBackendID()))
607      {
608        errors.add(ERR_BACKEND_ALREADY_EXISTS.get(backendName));
609        setPrimaryInvalid(lBackend);
610      }
611    }
612
613    return backendName;
614  }
615
616  private String validateBaseDN(final String backendName, final Set<BackendDescriptor> existingBackends,
617      final Set<LocalizableMessage> errors)
618  {
619    String dn = baseDN.getText();
620    if (dn.trim().length() == 0)
621    {
622      errors.add(ERR_NEW_BASE_DN_VALUE_REQUIRED.get());
623      setPrimaryInvalid(lDirectoryBaseDN);
624      return dn;
625    }
626
627    try
628    {
629      final DN theDN = DN.valueOf(dn);
630      for (final BackendDescriptor backend : existingBackends)
631      {
632        for (final BaseDNDescriptor baseDN : backend.getBaseDns())
633        {
634          if (baseDN.getDn().equals(theDN))
635          {
636            return invalidBaseDNValue(dn, ERR_BASE_DN_ALREADY_EXISTS.get(dn), errors);
637          }
638          else if (baseDN.getDn().isAncestorOf(theDN) && backendName.equalsIgnoreCase(backend.getBackendID()))
639          {
640            return invalidBaseDNValue(dn, ERR_BASE_DN_ANCESTOR_EXISTS.get(baseDN.getDn()), errors);
641          }
642          else if (theDN.isAncestorOf(baseDN.getDn()) && backendName.equalsIgnoreCase(backend.getBackendID()))
643          {
644            return invalidBaseDNValue(dn, ERR_BASE_DN_DN_IS_ANCESTOR_OF.get(baseDN.getDn()), errors);
645          }
646        }
647      }
648    }
649    catch (OpenDsException oe)
650    {
651      errors.add(INFO_CTRL_PANEL_INVALID_DN_DETAILS.get(dn, oe.getMessageObject()));
652      setPrimaryInvalid(lDirectoryBaseDN);
653    }
654
655    return dn;
656  }
657
658  /** Mark the provided base DN as invalid with the provided reason and return it. */
659  private String invalidBaseDNValue(final String dn, final LocalizableMessage errorMsg,
660      final Set<LocalizableMessage> errors)
661  {
662    errors.add(errorMsg);
663    setPrimaryInvalid(lDirectoryBaseDN);
664    return dn;
665  }
666
667  private void validateImportLDIFFilePath(final Set<LocalizableMessage> errors)
668  {
669    // TODO: what happens with sub-suffixes?
670    if (importDataFromLDIF.isSelected())
671    {
672      String ldifPath = path.getText();
673      if (ldifPath == null || "".equals(ldifPath.trim()))
674      {
675        errors.add(INFO_NO_LDIF_PATH.get());
676        setSecondaryInvalid(lPath);
677      }
678      else if (isLocal() && !Utils.fileExists(ldifPath))
679      {
680        errors.add(INFO_LDIF_FILE_DOES_NOT_EXIST.get());
681        setSecondaryInvalid(lPath);
682      }
683    }
684  }
685
686  private void validateAutomaticallyGenerated(final Set<LocalizableMessage> errors)
687  {
688    if (importAutomaticallyGenerated.isSelected())
689    {
690      final int minValue = 1;
691      final int maxValue = isLocal() ? MAX_ENTRIES_NUMBER_GENERATED_LOCAL : MAX_ENTRIES_NUMBER_GENERATED;
692      final LocalizableMessage errorMsg = ERR_NUMBER_OF_ENTRIES_INVALID.get(minValue, maxValue);
693      if (!checkIntValue(errors, numberOfEntries.getText(), minValue, maxValue, errorMsg))
694      {
695        setSecondaryInvalid(lNumberOfEntries);
696      }
697    }
698  }
699
700  private String getBackendName()
701  {
702    Object backendName = backends.getSelectedItem();
703    if (NEW_BACKEND_TEXT.equals(backendName))
704    {
705      return newBackend.getText().trim();
706    }
707    else if (backendName != null)
708    {
709      return backendName.toString();
710    }
711
712    return null;
713  }
714
715  private BackendTypeUIAdapter getSelectedBackendType()
716  {
717    return (BackendTypeUIAdapter) backendTypes.getSelectedItem();
718  }
719
720  private boolean isNewBackend()
721  {
722    return NEW_BACKEND_TEXT.equals(backends.getSelectedItem());
723  }
724
725  /** The task in charge of creating the base DN (and if required, the backend). */
726  protected class NewBaseDNTask extends Task
727  {
728    private final Set<String> backendSet;
729    private final String newBaseDN;
730    private int progressAfterConfigurationUpdate = -1;
731
732    /**
733     * The constructor of the task.
734     *
735     * @param info
736     *          the control panel info.
737     * @param dlg
738     *          the progress dialog that shows the progress of the task.
739     */
740    public NewBaseDNTask(ControlPanelInfo info, ProgressDialog dlg)
741    {
742      super(info, dlg);
743      backendSet = new HashSet<>();
744      backendSet.add(getBackendName());
745      newBaseDN = baseDN.getText();
746
747      if (onlyCreateBaseEntry.isSelected())
748      {
749        progressAfterConfigurationUpdate = 40;
750      }
751      else if (leaveDatabaseEmpty.isSelected())
752      {
753        progressAfterConfigurationUpdate = 90;
754      }
755      else if (importAutomaticallyGenerated.isSelected())
756      {
757        int nEntries = Integer.parseInt(numberOfEntries.getText().trim());
758        if (nEntries < 500)
759        {
760          progressAfterConfigurationUpdate = 30;
761        }
762        else if (nEntries < 3000)
763        {
764          progressAfterConfigurationUpdate = 15;
765        }
766        else
767        {
768          progressAfterConfigurationUpdate = 5;
769        }
770      }
771    }
772
773    /** {@inheritDoc} */
774    @Override
775    public Type getType()
776    {
777      return Type.NEW_BASEDN;
778    }
779
780    /** {@inheritDoc} */
781    @Override
782    public LocalizableMessage getTaskDescription()
783    {
784      return INFO_CTRL_PANEL_NEW_BASE_DN_TASK_DESCRIPTION.get(newBaseDN, backendSet.iterator().next());
785    }
786
787    /** {@inheritDoc} */
788    @Override
789    public boolean canLaunch(Task taskToBeLaunched, Collection<LocalizableMessage> incompatibilityReasons)
790    {
791      boolean canLaunch = true;
792      if (state == State.RUNNING && runningOnSameServer(taskToBeLaunched))
793      {
794        // All the operations are incompatible if they apply to this backend.
795        Set<String> backends = new TreeSet<>(taskToBeLaunched.getBackends());
796        backends.retainAll(getBackends());
797        if (!backends.isEmpty())
798        {
799          incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched));
800          canLaunch = false;
801        }
802      }
803      return canLaunch;
804    }
805
806    private String getDataCommandLineToDisplay()
807    {
808      StringBuilder sb = new StringBuilder();
809      sb.append(getDataCommandLineName());
810      Collection<String> args = getObfuscatedCommandLineArguments(getDataCommandLineArguments(path.getText(), false));
811      args.removeAll(getConfigCommandLineArguments());
812      for (String arg : args)
813      {
814        sb.append(" ").append(CommandBuilder.escapeValue(arg));
815      }
816      return sb.toString();
817    }
818
819    private String getDataCommandLineName()
820    {
821      if (!leaveDatabaseEmpty.isSelected())
822      {
823        return getCommandLinePath(isLocal() ? "import-ldif" : "ldapmodify");
824      }
825
826      return null;
827    }
828
829    /**
830     * Returns the arguments of the command-line that can be used to generate
831     * the data.
832     *
833     * @param ldifFile
834     *          the LDIF file.
835     * @param useTemplate
836     *          whether to use a template or not.
837     * @return the arguments of the command-line that can be used to generate
838     *         the data.
839     */
840    private List<String> getDataCommandLineArguments(String ldifFile, boolean useTemplate)
841    {
842      List<String> args = new ArrayList<>();
843      if (!leaveDatabaseEmpty.isSelected())
844      {
845        if (isLocal())
846        {
847          if (!useTemplate)
848          {
849            args.add("--ldifFile");
850            args.add(ldifFile);
851          }
852          else
853          {
854            args.add("--templateFile");
855            args.add(ldifFile);
856            args.add("--randomSeed");
857            args.add("0");
858          }
859          args.add("--backendID");
860          args.add(getBackendName());
861          args.add("--append");
862        }
863        else
864        {
865          // If we are not local, we use ldapmodify to update the contents.
866          args.add("-a");
867          args.add("-f");
868          args.add(ldifFile);
869        }
870        args.addAll(getConnectionCommandLineArguments(true, !isLocal()));
871
872        if (isServerRunning() && isLocal())
873        {
874          args.addAll(getConfigCommandLineArguments());
875        }
876
877        args.add(getNoPropertiesFileArgument());
878      }
879
880      return args;
881    }
882
883    private void updateConfigurationOnline() throws OpenDsException
884    {
885      SwingUtilities.invokeLater(new Runnable()
886      {
887        @Override
888        public void run()
889        {
890          List<String> args = getObfuscatedCommandLineArguments(getDSConfigCommandLineArguments());
891          args.removeAll(getConfigCommandLineArguments());
892          printEquivalentCommandLine(
893              getConfigCommandLineFullPath(), args, INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_CREATE_BASE_DN.get());
894        }
895      });
896
897      performTask();
898      printTaskDone();
899      if (isNewBackend())
900      {
901        createAdditionalIndexes();
902      }
903      refreshProgressBar();
904    }
905
906    private void updateConfigurationOffline() throws OpenDsException
907    {
908      boolean configHandlerUpdated = false;
909      try
910      {
911        getInfo().stopPooling();
912        if (getInfo().mustDeregisterConfig())
913        {
914          DirectoryServer.deregisterBaseDN(DN.valueOf("cn=config"));
915        }
916        DirectoryServer.getInstance().initializeConfiguration(
917            ConfigFileHandler.class.getName(), ConfigReader.configFile);
918        getInfo().setMustDeregisterConfig(true);
919        configHandlerUpdated = true;
920
921        performTask();
922        printTaskDone();
923        refreshProgressBar();
924      }
925      finally
926      {
927        if (configHandlerUpdated)
928        {
929          DirectoryServer.getInstance().initializeConfiguration(ConfigReader.configClassName, ConfigReader.configFile);
930          getInfo().startPooling();
931        }
932      }
933    }
934
935    private void printCreateNewBackendProgress(final String backendName) throws OpenDsException
936    {
937      SwingUtilities.invokeLater(new Runnable()
938      {
939        @Override
940        public void run()
941        {
942          LocalizableMessage message = INFO_CTRL_PANEL_CREATING_BACKEND_PROGRESS.get(backendName, newBaseDN);
943          getProgressDialog().appendProgressHtml(
944              Utilities.getProgressWithPoints(message, ColorAndFontConstants.progressFont));
945        }
946      });
947    }
948
949    private void performTask() throws OpenDsException
950    {
951      final String backendName = getBackendName();
952      if (isNewBackend())
953      {
954        printCreateNewBackendProgress(backendName);
955        createBackend(backendName);
956      }
957      else
958      {
959        printCreateNewBaseDNProgress(backendName);
960        addNewBaseDN(backendName);
961      }
962    }
963
964    private void createBackend(String backendName) throws OpenDsException
965    {
966      if (!isServerRunning())
967      {
968        createBackendOffline(backendName);
969        return;
970      }
971
972      createBackendOnline(backendName);
973    }
974
975    private void createBackendOffline(String backendName) throws OpenDsException
976    {
977      try
978      {
979        Set<org.forgerock.opendj.ldap.DN> baseDN = Collections.singleton(Converters.from(DN.valueOf(newBaseDN)));
980        BackendCreationHelper.createBackendOffline(backendName, baseDN, getSelectedBackendType().getBackend());
981      }
982      catch (Exception e)
983      {
984        throw new OfflineUpdateException(ERROR_CTRL_PANEL_CREATE_NEW_BACKEND.get(backendName, e.getMessage()), e);
985      }
986    }
987
988    @RemoveOnceNewConfigFrameworkIsUsed("Use BackendCreationHelper.createBackend(...)")
989    private void createBackendOnline(String backendName) throws OpenDsException
990    {
991      final RootCfgClient root = getRootConfigurationClient();
992      final BackendCfgClient backend =
993          root.createBackend(getSelectedBackendType().getLegacyConfigurationFrameworkBackend(), backendName, null);
994      backend.setEnabled(true);
995      backend.setBaseDN(Collections.singleton(DN.valueOf(newBaseDN)));
996      backend.setBackendId(backendName);
997      backend.setWritabilityMode(BackendCfgDefn.WritabilityMode.ENABLED);
998      backend.commit();
999    }
1000
1001    private RootCfgClient getRootConfigurationClient()
1002    {
1003      final JNDIDirContextAdaptor jndiContext = JNDIDirContextAdaptor.adapt(getInfo().getDirContext());
1004      return LDAPManagementContext.createFromContext(jndiContext).getRootConfiguration();
1005    }
1006
1007    private void addNewBaseDN(String backendName) throws OpenDsException
1008    {
1009      if (!isServerRunning())
1010      {
1011        addNewBaseDNOffline(backendName);
1012        return;
1013      }
1014
1015      final BackendCfgClient backend = getRootConfigurationClient().getBackend(backendName);
1016      final Set<DN> baseDNs = backend.getBaseDN();
1017      baseDNs.add(DN.valueOf(newBaseDN));
1018      backend.setBaseDN(baseDNs);
1019      backend.commit();
1020    }
1021
1022    private void addNewBaseDNOffline(String backendName) throws OpenDsException
1023    {
1024      try
1025      {
1026        getInfo().initializeConfigurationFramework();
1027        final File config = Installation.getLocal().getCurrentConfigurationFile();
1028        final LDAPProfile profile = LDAPProfile.getInstance();
1029        try (org.forgerock.opendj.config.client.ManagementContext context =
1030            org.forgerock.opendj.config.client.ldap.LDAPManagementContext.newLDIFManagementContext(config, profile))
1031        {
1032          final org.forgerock.opendj.server.config.client.BackendCfgClient backend =
1033              context.getRootConfiguration().getBackend(backendName);
1034          final SortedSet<org.forgerock.opendj.ldap.DN> baseDNs = backend.getBaseDN();
1035          baseDNs.add(org.forgerock.opendj.ldap.DN.valueOf(newBaseDN));
1036          backend.setBaseDN(baseDNs);
1037          backend.commit();
1038        }
1039      }
1040      catch (Exception e)
1041      {
1042        throw new OfflineUpdateException(LocalizableMessage.raw(e.getMessage()), e);
1043      }
1044    }
1045
1046    private void createAdditionalIndexes() throws OpenDsException
1047    {
1048      final String backendName = getBackendName();
1049      displayCreateAdditionalIndexesDsConfigCmdLine();
1050      final RootCfgClient root = getRootConfigurationClient();
1051      if (isLocalDBBackend())
1052      {
1053        addJEDefaultIndexes((LocalDBBackendCfgClient) root.getBackend(backendName));
1054      }
1055      else
1056      {
1057        addBackendDefaultIndexes((PluggableBackendCfgClient) root.getBackend(backendName));
1058      }
1059      displayCreateAdditionalIndexesDone();
1060    }
1061
1062    @RemoveOnceLocalDBBackendIsPluggable
1063    private void addJEDefaultIndexes(final LocalDBBackendCfgClient jeBackendCfgClient) throws AdminException
1064    {
1065      for (DefaultIndex defaultIndex : BackendCreationHelper.DEFAULT_INDEXES)
1066      {
1067        final LocalDBIndexCfgClient jeIndex =
1068            jeBackendCfgClient.createLocalDBIndex(LocalDBIndexCfgDefn.getInstance(), defaultIndex.getName(), null);
1069
1070        final List<LocalDBIndexCfgDefn.IndexType> indexTypes = new LinkedList<>();
1071        indexTypes.add(LocalDBIndexCfgDefn.IndexType.EQUALITY);
1072        if (defaultIndex.shouldCreateSubstringIndex())
1073        {
1074          indexTypes.add(LocalDBIndexCfgDefn.IndexType.SUBSTRING);
1075        }
1076        jeIndex.setIndexType(indexTypes);
1077        jeIndex.commit();
1078      }
1079    }
1080
1081    private void addBackendDefaultIndexes(PluggableBackendCfgClient backendCfgClient) throws AdminException
1082    {
1083      for (DefaultIndex defaultIndex : BackendCreationHelper.DEFAULT_INDEXES)
1084      {
1085        final BackendIndexCfgClient index = backendCfgClient.createBackendIndex(
1086            BackendIndexCfgDefn.getInstance(), defaultIndex.getName(), null);
1087
1088        final List<IndexType> indexTypes = new LinkedList<>();
1089        indexTypes.add(IndexType.EQUALITY);
1090        if (defaultIndex.shouldCreateSubstringIndex())
1091        {
1092          indexTypes.add(IndexType.SUBSTRING);
1093        }
1094        index.setIndexType(indexTypes);
1095        index.commit();
1096      }
1097    }
1098
1099    private void printCreateNewBaseDNProgress(final String backendName) throws OpenDsException
1100    {
1101      SwingUtilities.invokeLater(new Runnable()
1102      {
1103        @Override
1104        public void run()
1105        {
1106          LocalizableMessage message = INFO_CTRL_PANEL_CREATING_BASE_DN_PROGRESS.get(newBaseDN, backendName);
1107          getProgressDialog().appendProgressHtml(
1108              Utilities.getProgressWithPoints(message, ColorAndFontConstants.progressFont));
1109        }
1110      });
1111    }
1112
1113    private void printTaskDone()
1114    {
1115      SwingUtilities.invokeLater(new Runnable()
1116      {
1117        @Override
1118        public void run()
1119        {
1120          getProgressDialog().appendProgressHtml(
1121              Utilities.getProgressDone(ColorAndFontConstants.progressFont) + "<br><br>");
1122        }
1123      });
1124    }
1125
1126    private void refreshProgressBar()
1127    {
1128      if (progressAfterConfigurationUpdate > 0)
1129      {
1130        SwingUtilities.invokeLater(new Runnable()
1131        {
1132          @Override
1133          public void run()
1134          {
1135            getProgressDialog().getProgressBar().setIndeterminate(false);
1136            getProgressDialog().getProgressBar().setValue(progressAfterConfigurationUpdate);
1137          }
1138        });
1139      }
1140    }
1141
1142    private void displayCreateAdditionalIndexesDsConfigCmdLine()
1143    {
1144      final List<List<String>> argsArray = new ArrayList<>();
1145      for (DefaultIndex defaultIndex : BackendCreationHelper.DEFAULT_INDEXES)
1146      {
1147        argsArray.add(getCreateIndexCommandLineArguments(defaultIndex));
1148      }
1149
1150      final StringBuilder sb = new StringBuilder();
1151      for (List<String> args : argsArray)
1152      {
1153        sb.append(getEquivalentCommandLine(getCommandLinePath("dsconfig"), getObfuscatedCommandLineArguments(args)));
1154        sb.append("<br><br>");
1155      }
1156
1157      SwingUtilities.invokeLater(new Runnable()
1158      {
1159        @Override
1160        public void run()
1161        {
1162          getProgressDialog().appendProgressHtml(Utilities.applyFont(
1163              INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_CREATE_ADDITIONAL_INDEXES.get()
1164              + "<br><br><b>" + sb + "</b>", ColorAndFontConstants.progressFont));
1165          getProgressDialog().appendProgressHtml(Utilities.getProgressWithPoints(
1166              INFO_CTRL_PANEL_CREATING_ADDITIONAL_INDEXES_PROGRESS.get(), ColorAndFontConstants.progressFont));
1167        }
1168      });
1169    }
1170
1171    private List<String> getCreateIndexCommandLineArguments(final DefaultIndex defaultIndex)
1172    {
1173      final List<String> args = new ArrayList<>();
1174      args.add(isLocalDBBackend() ? "create-local-db-index" : "create-backend-index");
1175      args.add("--backend-name");
1176      args.add(getBackendName());
1177      args.add("--type");
1178      args.add("generic");
1179      args.add("--index-name");
1180      args.add(defaultIndex.getName());
1181      args.add("--set");
1182      args.add("index-type:" + IndexTypeDescriptor.EQUALITY.toBackendIndexType());
1183      if (defaultIndex.shouldCreateSubstringIndex())
1184      {
1185        args.add("--set");
1186        args.add("index-type:" + IndexTypeDescriptor.SUBSTRING.toBackendIndexType());
1187      }
1188      args.addAll(getConnectionCommandLineArguments());
1189      args.add(getNoPropertiesFileArgument());
1190      args.add("--no-prompt");
1191
1192      return args;
1193    }
1194
1195    private void displayCreateAdditionalIndexesDone()
1196    {
1197      SwingUtilities.invokeLater(new Runnable()
1198      {
1199        @Override
1200        public void run()
1201        {
1202          getProgressDialog().appendProgressHtml(
1203              Utilities.getProgressDone(ColorAndFontConstants.progressFont) + "<br><br>");
1204        }
1205      });
1206    }
1207
1208    @RemoveOnceLocalDBBackendIsPluggable
1209    private boolean isLocalDBBackend()
1210    {
1211      return getSelectedBackendType().getBackend()
1212          instanceof org.forgerock.opendj.server.config.meta.LocalDBBackendCfgDefn;
1213    }
1214
1215    /**
1216     * Creates the data in the new base DN.
1217     *
1218     * @throws OpenDsException
1219     *           if there is an error importing contents.
1220     * @throws IOException
1221     *           if there is an err
1222     */
1223    private void updateData() throws OpenDsException, IOException
1224    {
1225      final boolean leaveEmpty = leaveDatabaseEmpty.isSelected();
1226      final boolean createBaseEntry = onlyCreateBaseEntry.isSelected();
1227      final boolean importLDIF = importDataFromLDIF.isSelected();
1228      final boolean generateData = !leaveEmpty && !createBaseEntry && !importLDIF;
1229      final String nEntries = numberOfEntries.getText();
1230      final String ldif = path.getText();
1231
1232      if (leaveEmpty)
1233      {
1234        state = State.FINISHED_SUCCESSFULLY;
1235      }
1236      else
1237      {
1238        final ProgressDialog progressDialog = getProgressDialog();
1239        String ldifFile;
1240        if (importLDIF)
1241        {
1242          ldifFile = ldif;
1243          final String cmdLine = getDataCommandLineToDisplay();
1244          SwingUtilities.invokeLater(new Runnable()
1245          {
1246            @Override
1247            public void run()
1248            {
1249              progressDialog.appendProgressHtml(Utilities.applyFont("Equivalent command line:<br><b>" + cmdLine
1250                  + "</b><br><br>", ColorAndFontConstants.progressFont));
1251            }
1252          });
1253        }
1254        else if (createBaseEntry)
1255        {
1256          SwingUtilities.invokeLater(new Runnable()
1257          {
1258            @Override
1259            public void run()
1260            {
1261              progressDialog.appendProgressHtml(Utilities.getProgressWithPoints(
1262                  INFO_PROGRESS_CREATING_BASE_ENTRY.get(newBaseDN), ColorAndFontConstants.progressFont));
1263            }
1264          });
1265          InstallerHelper helper = new InstallerHelper();
1266          File f = helper.createBaseEntryTempFile(newBaseDN);
1267          ldifFile = f.getAbsolutePath();
1268        }
1269        else
1270        {
1271          SwingUtilities.invokeLater(new Runnable()
1272          {
1273            @Override
1274            public void run()
1275            {
1276              if (isLocal())
1277              {
1278                progressDialog.appendProgressHtml(Utilities.applyFont(
1279                    INFO_PROGRESS_IMPORT_AUTOMATICALLY_GENERATED.get(nEntries).toString(),
1280                    ColorAndFontConstants.progressFont) + "<br>");
1281              }
1282              else
1283              {
1284                getProgressDialog().appendProgressHtml(Utilities.getProgressWithPoints(
1285                    INFO_PROGRESS_IMPORT_AUTOMATICALLY_GENERATED_REMOTE.get(nEntries),
1286                    ColorAndFontConstants.progressFont));
1287              }
1288            }
1289          });
1290
1291          File f = SetupUtils.createTemplateFile(newBaseDN, Integer.parseInt(nEntries));
1292          if (!isLocal())
1293          {
1294            File tempFile = File.createTempFile("opendj-control-panel", ".ldif");
1295            tempFile.deleteOnExit();
1296            ldifFile = tempFile.getAbsolutePath();
1297
1298            // Create the LDIF file locally using make-ldif
1299            List<String> makeLDIFArgs = new ArrayList<>();
1300            makeLDIFArgs.add("--templateFile");
1301            makeLDIFArgs.add(f.getAbsolutePath());
1302            makeLDIFArgs.add("--ldifFile");
1303            makeLDIFArgs.add(ldifFile);
1304            makeLDIFArgs.add("--randomSeed");
1305            makeLDIFArgs.add("0");
1306            makeLDIFArgs.add("--resourcePath");
1307
1308            File makeLDIFPath = new File(Installation.getLocal().getConfigurationDirectory(), "MakeLDIF");
1309            makeLDIFArgs.add(makeLDIFPath.getAbsolutePath());
1310            makeLDIFArgs.addAll(getConfigCommandLineArguments());
1311
1312            MakeLDIF makeLDIF = new MakeLDIF();
1313            String[] array = new String[makeLDIFArgs.size()];
1314            makeLDIFArgs.toArray(array);
1315            returnCode = makeLDIF.makeLDIFMain(array, false, false, outPrintStream, errorPrintStream);
1316            f.delete();
1317
1318            if (returnCode != 0)
1319            {
1320              throw new OnlineUpdateException(ERR_CTRL_PANEL_ERROR_CREATING_NEW_DATA_LDIF.get(returnCode), null);
1321            }
1322          }
1323          else
1324          {
1325            ldifFile = f.getAbsolutePath();
1326          }
1327        }
1328
1329        List<String> arguments = getDataCommandLineArguments(ldifFile, generateData);
1330        String[] args = new String[arguments.size()];
1331        arguments.toArray(args);
1332        if (createBaseEntry || !isLocal())
1333        {
1334          outPrintStream.setNotifyListeners(false);
1335          errorPrintStream.setNotifyListeners(false);
1336        }
1337        try
1338        {
1339          if (isServerRunning())
1340          {
1341            if (isLocal() || importLDIF)
1342            {
1343              returnCode = ImportLDIF.mainImportLDIF(args, false, outPrintStream, errorPrintStream);
1344            }
1345            else
1346            {
1347              returnCode = LDAPModify.mainModify(args, false, outPrintStream, errorPrintStream);
1348            }
1349          }
1350          else
1351          {
1352            returnCode = executeCommandLine(getDataCommandLineName(), args);
1353          }
1354        }
1355        finally
1356        {
1357          outPrintStream.setNotifyListeners(true);
1358          errorPrintStream.setNotifyListeners(true);
1359        }
1360
1361        if (returnCode != 0)
1362        {
1363          state = State.FINISHED_WITH_ERROR;
1364        }
1365        else
1366        {
1367          if (createBaseEntry || (!isLocal() && generateData))
1368          {
1369            SwingUtilities.invokeLater(new Runnable()
1370            {
1371              @Override
1372              public void run()
1373              {
1374                progressDialog.appendProgressHtml(Utilities.getProgressDone(ColorAndFontConstants.progressFont));
1375              }
1376            });
1377          }
1378          state = State.FINISHED_SUCCESSFULLY;
1379        }
1380      }
1381    }
1382
1383    /** {@inheritDoc} */
1384    @Override
1385    protected String getCommandLinePath()
1386    {
1387      return null;
1388    }
1389
1390    /** {@inheritDoc} */
1391    @Override
1392    protected List<String> getCommandLineArguments()
1393    {
1394      return new ArrayList<>();
1395    }
1396
1397    private String getConfigCommandLineFullPath()
1398    {
1399      return isServerRunning() ? getCommandLinePath("dsconfig") : null;
1400    }
1401
1402    private List<String> getDSConfigCommandLineArguments()
1403    {
1404      List<String> args = new ArrayList<>();
1405      if (isServerRunning())
1406      {
1407        if (isNewBackend())
1408        {
1409          args.add("create-backend");
1410          args.add("--backend-name");
1411          args.add(getBackendName());
1412          args.add("--set");
1413          args.add("base-dn:" + newBaseDN);
1414          args.add("--set");
1415          args.add("enabled:true");
1416          args.add("--type");
1417          args.add(BackendTypeHelper.filterSchemaBackendName(getSelectedBackendType().getBackend().getName()));
1418        }
1419        else
1420        {
1421          args.add("set-backend-prop");
1422          args.add("--backend-name");
1423          args.add(getBackendName());
1424          args.add("--add");
1425          args.add("base-dn:" + newBaseDN);
1426        }
1427        args.addAll(getConnectionCommandLineArguments());
1428        args.add(getNoPropertiesFileArgument());
1429        args.add("--no-prompt");
1430      }
1431      return args;
1432    }
1433
1434    /** {@inheritDoc} */
1435    @Override
1436    public void runTask()
1437    {
1438      state = State.RUNNING;
1439      lastException = null;
1440
1441      try
1442      {
1443        if (isServerRunning())
1444        {
1445          updateConfigurationOnline();
1446        }
1447        else
1448        {
1449          updateConfigurationOffline();
1450        }
1451        updateData();
1452      }
1453      catch (Throwable t)
1454      {
1455        lastException = t;
1456        state = State.FINISHED_WITH_ERROR;
1457      }
1458    }
1459
1460    /** {@inheritDoc} */
1461    @Override
1462    public Set<String> getBackends()
1463    {
1464      return backendSet;
1465    }
1466  }
1467}