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-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.guitools.controlpanel.ui;
028
029import static org.opends.messages.AdminToolMessages.*;
030import static org.opends.messages.QuickSetupMessages.*;
031import static com.forgerock.opendj.cli.Utils.OBFUSCATED_VALUE;
032
033import java.awt.Component;
034import java.awt.GridBagConstraints;
035import java.io.File;
036import java.util.ArrayList;
037import java.util.Collection;
038import java.util.HashSet;
039import java.util.LinkedHashSet;
040import java.util.Set;
041import java.util.TreeSet;
042
043import javax.swing.ButtonGroup;
044import javax.swing.DefaultComboBoxModel;
045import javax.swing.JButton;
046import javax.swing.JCheckBox;
047import javax.swing.JComboBox;
048import javax.swing.JLabel;
049import javax.swing.JRadioButton;
050import javax.swing.JTextField;
051import javax.swing.SwingUtilities;
052import javax.swing.event.ChangeEvent;
053import javax.swing.event.ChangeListener;
054import javax.swing.event.DocumentEvent;
055import javax.swing.event.DocumentListener;
056
057import org.opends.admin.ads.util.ConnectionUtils;
058import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
059import org.opends.guitools.controlpanel.datamodel.BaseDNDescriptor;
060import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
061import org.opends.guitools.controlpanel.datamodel.ServerDescriptor;
062import org.opends.guitools.controlpanel.event.BrowseActionListener;
063import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
064import org.opends.guitools.controlpanel.task.Task;
065import org.opends.guitools.controlpanel.util.Utilities;
066import org.forgerock.i18n.LocalizableMessage;
067import org.opends.quicksetup.ui.UIFactory;
068import org.opends.quicksetup.util.Utils;
069import org.opends.server.tools.ImportLDIF;
070import org.opends.server.tools.dsreplication.ReplicationCliArgumentParser;
071import org.opends.server.tools.dsreplication.ReplicationCliException;
072import org.opends.server.tools.dsreplication.ReplicationCliMain;
073import org.opends.server.types.DN;
074
075/**
076 * The panel where the user can import the contents of an LDIF file to the
077 * server.
078 */
079public class ImportLDIFPanel extends InclusionExclusionPanel
080{
081  private static final long serialVersionUID = 1143246529610229229L;
082  private JComboBox backends;
083  private JTextField file;
084  private JCheckBox dataCompressed;
085  private JRadioButton overwrite;
086  private JRadioButton append;
087  private JCheckBox replaceEntries;
088  private JCheckBox rejectNotSchemaCompliant;
089  private JCheckBox doDNValidationAfter;
090  private JCheckBox writeRejects;
091  private JCheckBox writeSkips;
092  private JTextField threads;
093  private JTextField rejectsFile;
094  private JTextField skipsFile;
095  private JCheckBox overwriteRejectsFile;
096  private JCheckBox overwriteSkipsFile;
097  private JButton bBrowse;
098  private JButton rejectsBrowse;
099  private JButton skipsBrowse;
100
101  private JLabel lBackend;
102  private JLabel lNoBackendsFound;
103  private JLabel lFile;
104  private JLabel lImportType;
105  private JLabel lSchemaValidation;
106  private JLabel lDNValidation;
107  private JLabel lThreads;
108  private JLabel lRejectsFile;
109  private JLabel lSkipsFile;
110  private JLabel lRemoteFileHelp;
111  private JLabel lRemoteRejectsHelp;
112  private JLabel lRemoteSkipsHelp;
113
114  private DocumentListener documentListener;
115
116  /**
117   * Default constructor.
118   *
119   */
120  public ImportLDIFPanel()
121  {
122    super();
123    createLayout();
124  }
125
126  /** {@inheritDoc} */
127  @Override
128  public LocalizableMessage getTitle()
129  {
130    return INFO_CTRL_PANEL_IMPORT_LDIF_TITLE.get();
131  }
132
133  /** {@inheritDoc} */
134  @Override
135  public Component getPreferredFocusComponent()
136  {
137    return file;
138  }
139
140  /** {@inheritDoc} */
141  @Override
142  public void toBeDisplayed(boolean visible)
143  {
144    if (visible)
145    {
146      documentListener.changedUpdate(null);
147    }
148  }
149
150  /**
151   * Creates the layout of the panel (but the contents are not populated here).
152   */
153  private void createLayout()
154  {
155    GridBagConstraints gbc = new GridBagConstraints();
156    gbc.anchor = GridBagConstraints.WEST;
157    gbc.gridx = 0;
158    gbc.gridy = 0;
159    gbc.gridwidth = 3;
160    addErrorPane(gbc);
161
162    gbc.gridy ++;
163    gbc.weightx = 0.0;
164    gbc.gridwidth = 1;
165    gbc.fill = GridBagConstraints.NONE;
166    lBackend = Utilities.createPrimaryLabel(
167        INFO_CTRL_PANEL_BACKEND_LABEL.get());
168    add(lBackend, gbc);
169    gbc.insets.left = 10;
170    gbc.gridx = 1;
171    backends = Utilities.createComboBox();
172    backends.setModel(new DefaultComboBoxModel(new String[]{}));
173    gbc.gridwidth = 2;
174    add(backends, gbc);
175    lNoBackendsFound = Utilities.createDefaultLabel(
176        INFO_CTRL_PANEL_NO_BACKENDS_FOUND_LABEL.get());
177    add(lNoBackendsFound, gbc);
178    lNoBackendsFound.setVisible(false);
179    gbc.insets.top = 10;
180    lBackend.setLabelFor(backends);
181    lNoBackendsFound.setLabelFor(lBackend);
182
183    gbc.gridx = 0;
184    gbc.gridy ++;
185    gbc.insets.left = 0;
186    gbc.gridwidth = 1;
187    lFile = Utilities.createPrimaryLabel(
188        INFO_CTRL_PANEL_FILE_TO_IMPORT_LABEL.get());
189    add(lFile, gbc);
190
191    gbc.gridx = 1;
192    gbc.insets.left = 10;
193    file = Utilities.createTextField();
194    lFile.setLabelFor(file);
195    documentListener = new DocumentListener()
196    {
197      /** {@inheritDoc} */
198      @Override
199      public void changedUpdate(DocumentEvent ev)
200      {
201        String text = file.getText().trim();
202        setEnabledOK(text != null && text.length() > 0 && !errorPane.isVisible());
203      }
204      /** {@inheritDoc} */
205      @Override
206      public void removeUpdate(DocumentEvent ev)
207      {
208        changedUpdate(ev);
209      }
210      /** {@inheritDoc} */
211      @Override
212      public void insertUpdate(DocumentEvent ev)
213      {
214        changedUpdate(ev);
215      }
216    };
217    file.getDocument().addDocumentListener(documentListener);
218    gbc.weightx = 1.0;
219    gbc.fill = GridBagConstraints.HORIZONTAL;
220    add(file, gbc);
221    bBrowse = Utilities.createButton(
222        INFO_CTRL_PANEL_BROWSE_BUTTON_LABEL.get());
223    bBrowse.addActionListener(
224        new BrowseActionListener(file,
225            BrowseActionListener.BrowseType.OPEN_LDIF_FILE,  this));
226    gbc.gridx = 2;
227    gbc.gridwidth = 1;
228    gbc.weightx = 0.0;
229    bBrowse.setOpaque(false);
230    add(bBrowse, gbc);
231
232    lRemoteFileHelp = Utilities.createInlineHelpLabel(
233        INFO_CTRL_PANEL_REMOTE_SERVER_PATH.get());
234    gbc.gridx = 1;
235    gbc.gridwidth = 2;
236    gbc.insets.top = 3;
237    gbc.insets.left = 10;
238    gbc.gridy ++;
239    add(lRemoteFileHelp, gbc);
240    lRemoteFileHelp.setLabelFor(file);
241
242    gbc.gridx = 1;
243    gbc.gridy ++;
244    gbc.insets.left = 30;
245    gbc.insets.top = 5;
246    gbc.gridwidth = 2;
247    dataCompressed = Utilities.createCheckBox(
248        INFO_CTRL_PANEL_DATA_IN_FILE_COMPRESSED.get());
249    dataCompressed.setOpaque(false);
250    add(dataCompressed, gbc);
251
252    gbc.gridx = 0;
253    gbc.gridy ++;
254    gbc.insets.left = 0;
255    gbc.insets.top = 10;
256    gbc.gridwidth = 1;
257    lImportType = Utilities.createPrimaryLabel(
258        INFO_CTRL_PANEL_IMPORT_TYPE_LABEL.get());
259    add(lImportType, gbc);
260
261    overwrite = Utilities.createRadioButton(
262        INFO_CTRL_PANEL_IMPORT_OVERWRITE_LABEL.get());
263    overwrite.setSelected(true);
264    lImportType.setLabelFor(overwrite);
265
266    append =
267      Utilities.createRadioButton(INFO_CTRL_PANEL_IMPORT_APPEND_LABEL.get());
268
269    ButtonGroup group = new ButtonGroup();
270    group.add(overwrite);
271    group.add(append);
272
273    gbc.insets.left = 10;
274    gbc.gridx = 1;
275    gbc.gridwidth = 2;
276    add(overwrite, gbc);
277    gbc.gridy ++;
278    gbc.insets.top = 5;
279    add(append, gbc);
280    append.addChangeListener(new ChangeListener()
281    {
282      /** {@inheritDoc} */
283      @Override
284      public void stateChanged(ChangeEvent ev)
285      {
286        replaceEntries.setEnabled(append.isSelected());
287      }
288    });
289
290    replaceEntries =
291      Utilities.createCheckBox(INFO_CTRL_PANEL_IMPORT_REPLACE_ENTRIES.get());
292    replaceEntries.setOpaque(false);
293    replaceEntries.setEnabled(false);
294    gbc.insets.left = 30;
295    gbc.gridy ++;
296    add(replaceEntries, gbc);
297
298    gbc.gridx = 0;
299    gbc.gridy ++;
300    gbc.insets.left = 0;
301    gbc.insets.top = 10;
302    gbc.gridwidth = 1;
303    lSchemaValidation = Utilities.createPrimaryLabel(
304        INFO_CTRL_PANEL_SCHEMA_VALIDATION_LABEL.get());
305    add(lSchemaValidation, gbc);
306
307    gbc.gridx = 1;
308    rejectNotSchemaCompliant = Utilities.createCheckBox(
309        INFO_CTRL_PANEL_REJECT_NOT_SCHEMA_COMPLIANT_LABEL.get());
310    rejectNotSchemaCompliant.setSelected(true);
311    gbc.insets.left = 10;
312    add(rejectNotSchemaCompliant, gbc);
313    lSchemaValidation.setLabelFor(rejectNotSchemaCompliant);
314
315    gbc.gridx = 0;
316    gbc.gridy ++;
317    gbc.insets.left = 0;
318    lDNValidation = Utilities.createPrimaryLabel(
319        INFO_CTRL_PANEL_DN_VALIDATION_LABEL.get());
320    add(lDNValidation, gbc);
321
322    gbc.gridx = 1;
323    doDNValidationAfter = Utilities.createCheckBox(
324        INFO_CTRL_PANEL_DO_DN_VALIDATION_LATER_LABEL.get());
325    doDNValidationAfter.setSelected(false);
326    gbc.insets.left = 10;
327    add(doDNValidationAfter, gbc);
328    lDNValidation.setLabelFor(doDNValidationAfter);
329
330    gbc.gridx = 0;
331    gbc.gridy ++;
332    gbc.insets.left = 0;
333    lThreads = Utilities.createPrimaryLabel(
334        INFO_CTRL_PANEL_IMPORT_THREADS_LABEL.get());
335    add(lThreads, gbc);
336
337    gbc.gridx = 1;
338    threads = Utilities.createShortTextField();
339    gbc.gridwidth = 2;
340    gbc.fill = GridBagConstraints.NONE;
341    threads.setToolTipText(
342        INFO_CTRL_PANEL_IMPORT_THREADS_TOOLTIP.get().toString());
343    gbc.insets.left = 10;
344    add(threads, gbc);
345    lThreads.setLabelFor(threads);
346
347    gbc.insets.top = 3;
348    gbc.gridy ++;
349    add(Utilities.createInlineHelpLabel(
350        INFO_CTRL_PANEL_IMPORT_THREADS_HELP.get()), gbc);
351
352    gbc.gridx = 0;
353    gbc.gridy ++;
354    gbc.insets.left = 0;
355    gbc.insets.top = 10;
356    gbc.gridwidth = 1;
357    lRejectsFile = Utilities.createPrimaryLabel(
358        INFO_CTRL_PANEL_REJECTS_FILE_LABEL.get());
359    add(lRejectsFile, gbc);
360
361    gbc.gridx = 1;
362    writeRejects = Utilities.createCheckBox(
363        INFO_CTRL_PANEL_WRITE_REJECTS_FILE_LABEL.get());
364    writeRejects.setSelected(false);
365    gbc.insets.left = 10;
366    add(writeRejects, gbc);
367    lRejectsFile.setLabelFor(writeRejects);
368
369    gbc.gridx = 1;
370    gbc.gridy++;
371    gbc.insets.left = 30;
372    gbc.insets.top = 5;
373    rejectsFile = Utilities.createTextField();
374    gbc.weightx = 1.0;
375    gbc.fill = GridBagConstraints.HORIZONTAL;
376    add(rejectsFile, gbc);
377    rejectsBrowse =
378      Utilities.createButton(INFO_CTRL_PANEL_BROWSE_BUTTON_LABEL.get());
379    rejectsBrowse.addActionListener(
380        new BrowseActionListener(rejectsFile,
381            BrowseActionListener.BrowseType.CREATE_GENERIC_FILE,  this));
382    gbc.gridx = 2;
383    gbc.gridwidth = 1;
384    gbc.weightx = 0.0;
385    gbc.insets.left = 10;
386    rejectsBrowse.setOpaque(false);
387    add(rejectsBrowse, gbc);
388
389    lRemoteRejectsHelp = Utilities.createInlineHelpLabel(
390        INFO_CTRL_PANEL_REMOTE_SERVER_PATH.get());
391    gbc.gridx = 1;
392    gbc.gridwidth = 2;
393    gbc.insets.top = 3;
394    gbc.insets.left = 10;
395    gbc.gridy ++;
396    add(lRemoteRejectsHelp, gbc);
397
398    gbc.gridx = 1;
399    gbc.gridy ++;
400    gbc.insets.left = 30;
401    gbc.gridwidth = 2;
402    overwriteRejectsFile = Utilities.createCheckBox(
403        INFO_CTRL_PANEL_OVERWRITE_REJECTS_FILE_LABEL.get());
404    overwriteRejectsFile.setOpaque(false);
405    add(overwriteRejectsFile, gbc);
406    lRemoteRejectsHelp.setLabelFor(overwriteRejectsFile);
407
408    ChangeListener changeListener = new ChangeListener()
409    {
410      /** {@inheritDoc} */
411      @Override
412      public void stateChanged(ChangeEvent ev)
413      {
414        rejectsFile.setEnabled(writeRejects.isSelected());
415        rejectsBrowse.setEnabled(writeRejects.isSelected());
416        overwriteRejectsFile.setEnabled(writeRejects.isSelected());
417      }
418    };
419    writeRejects.addChangeListener(changeListener);
420    writeRejects.setSelected(false);
421    changeListener.stateChanged(null);
422
423    gbc.gridx = 0;
424    gbc.gridy ++;
425    gbc.insets.left = 0;
426    gbc.insets.top = 10;
427    gbc.gridwidth = 1;
428    lSkipsFile = Utilities.createPrimaryLabel(
429        INFO_CTRL_PANEL_SKIPS_FILE_LABEL.get());
430    add(lSkipsFile, gbc);
431
432    gbc.gridx = 1;
433    writeSkips =
434      Utilities.createCheckBox(INFO_CTRL_PANEL_WRITE_SKIPS_FILE_LABEL.get());
435    writeSkips.setSelected(false);
436    gbc.insets.left = 10;
437    add(writeSkips, gbc);
438    lSkipsFile.setLabelFor(writeSkips);
439
440    gbc.gridx = 1;
441    gbc.gridy++;
442    gbc.insets.left = 30;
443    gbc.insets.top = 5;
444    skipsFile = Utilities.createTextField();
445    gbc.weightx = 1.0;
446    gbc.fill = GridBagConstraints.HORIZONTAL;
447    add(skipsFile, gbc);
448    skipsBrowse =
449      Utilities.createButton(INFO_CTRL_PANEL_BROWSE_BUTTON_LABEL.get());
450    skipsBrowse.addActionListener(
451        new BrowseActionListener(skipsFile,
452            BrowseActionListener.BrowseType.CREATE_GENERIC_FILE,  this));
453    gbc.gridx = 2;
454    gbc.gridwidth = 1;
455    gbc.weightx = 0.0;
456    gbc.insets.left = 10;
457    skipsBrowse.setOpaque(false);
458    add(skipsBrowse, gbc);
459
460    lRemoteSkipsHelp = Utilities.createInlineHelpLabel(
461        INFO_CTRL_PANEL_REMOTE_SERVER_PATH.get());
462    gbc.gridx = 1;
463    gbc.gridwidth = 2;
464    gbc.insets.top = 3;
465    gbc.insets.left = 10;
466    gbc.gridy ++;
467    add(lRemoteSkipsHelp, gbc);
468
469    gbc.gridx = 1;
470    gbc.gridy ++;
471    gbc.insets.left = 30;
472    gbc.gridwidth = 2;
473    overwriteSkipsFile = Utilities.createCheckBox(
474        INFO_CTRL_PANEL_OVERWRITE_SKIPS_FILE_LABEL.get());
475    overwriteSkipsFile.setOpaque(false);
476    add(overwriteSkipsFile, gbc);
477    lRemoteSkipsHelp.setLabelFor(overwriteSkipsFile);
478
479    changeListener = new ChangeListener()
480    {
481      /** {@inheritDoc} */
482      @Override
483      public void stateChanged(ChangeEvent ev)
484      {
485        skipsFile.setEnabled(writeSkips.isSelected());
486        skipsBrowse.setEnabled(writeSkips.isSelected());
487        overwriteSkipsFile.setEnabled(writeSkips.isSelected());
488      }
489    };
490    writeSkips.addChangeListener(changeListener);
491    writeSkips.setSelected(false);
492    changeListener.stateChanged(null);
493
494    changeListener = new ChangeListener()
495    {
496      /** {@inheritDoc} */
497      @Override
498      public void stateChanged(ChangeEvent ev)
499      {
500        if (ev.getSource() == overwriteSkipsFile)
501        {
502          overwriteRejectsFile.setSelected(overwriteSkipsFile.isSelected());
503        }
504        if (ev.getSource() == overwriteRejectsFile)
505        {
506          overwriteSkipsFile.setSelected(overwriteRejectsFile.isSelected());
507        }
508      }
509    };
510    overwriteRejectsFile.addChangeListener(changeListener);
511    overwriteSkipsFile.addChangeListener(changeListener);
512
513    gbc.insets.top = 10;
514    gbc.insets.left = 0;
515    gbc.gridy ++;
516    gbc.gridx = 0;
517    gbc.gridwidth = 3;
518    gbc.fill = GridBagConstraints.HORIZONTAL;
519    add(createDataExclusionOptions(new JLabel[]{}, new Component[]{}), gbc);
520    gbc.gridy ++;
521    gbc.insets.top = 15;
522    add(createDataInclusionOptions(new JLabel[]{}, new Component[]{}), gbc);
523
524    addBottomGlue(gbc);
525  }
526
527  /** {@inheritDoc} */
528  @Override
529  public void configurationChanged(ConfigurationChangeEvent ev)
530  {
531    ServerDescriptor desc = ev.getNewDescriptor();
532    updateSimpleBackendComboBoxModel(backends, lNoBackendsFound, desc);
533    updateErrorPaneAndOKButtonIfAuthRequired(desc,
534      isLocal() ? INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_FOR_IMPORT.get() :
535      INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get(desc.getHostname()));
536    SwingUtilities.invokeLater(new Runnable()
537    {
538      @Override
539      public void run()
540      {
541        lRemoteFileHelp.setVisible(!isLocal());
542        bBrowse.setVisible(isLocal());
543        rejectsBrowse.setVisible(isLocal());
544        skipsBrowse.setVisible(isLocal());
545        lRemoteRejectsHelp.setVisible(!isLocal());
546        lRemoteSkipsHelp.setVisible(!isLocal());
547      }
548    });
549  }
550
551  /** {@inheritDoc} */
552  @Override
553  protected void checkOKButtonEnable()
554  {
555    documentListener.changedUpdate(null);
556  }
557
558  /** {@inheritDoc} */
559  @Override
560  public void okClicked()
561  {
562    setPrimaryValid(lBackend);
563    setPrimaryValid(lFile);
564    setPrimaryValid(lRejectsFile);
565    setPrimaryValid(lSkipsFile);
566    setPrimaryValid(lThreads);
567    final LinkedHashSet<LocalizableMessage> errors = new LinkedHashSet<>();
568
569    String backendName = (String)backends.getSelectedItem();
570    if (backendName == null)
571    {
572      errors.add(ERR_CTRL_PANEL_NO_BACKEND_SELECTED.get());
573      setPrimaryInvalid(lBackend);
574    }
575
576    String ldifPath = file.getText();
577    if (ldifPath == null || "".equals(ldifPath.trim()))
578    {
579      errors.add(INFO_NO_LDIF_PATH.get());
580      setPrimaryInvalid(lFile);
581    } else if (isLocal() && !Utils.fileExists(ldifPath))
582    {
583      errors.add(INFO_LDIF_FILE_DOES_NOT_EXIST.get());
584      setPrimaryInvalid(lFile);
585    }
586
587    String sThread = threads.getText().trim();
588    if (sThread.length() > 0)
589    {
590      try
591      {
592        int threads = Integer.parseInt(sThread);
593        if (threads < 1)
594        {
595          errors.add(ERR_IMPORT_THREAD_NUMBER_INVALID.get());
596          setPrimaryInvalid(lThreads);
597        }
598      }
599      catch (Throwable t)
600      {
601        errors.add(ERR_IMPORT_THREAD_NUMBER_INVALID.get());
602        setPrimaryInvalid(lThreads);
603      }
604    }
605
606    if (writeRejects.isSelected())
607    {
608      String rejectPath = rejectsFile.getText();
609      if (rejectPath == null || "".equals(rejectPath.trim()))
610      {
611        errors.add(ERR_CTRL_PANEL_REJECTS_FILE_REQUIRED.get());
612        setPrimaryInvalid(lRejectsFile);
613      }
614      else if (writeSkips.isSelected()
615          && new File(rejectPath).equals(new File(skipsFile.getText())))
616      {
617        errors.add(ERR_CTRL_PANEL_REJECTS_AND_SKIPS_MUST_BE_DIFFERENT.get());
618        setPrimaryInvalid(lRejectsFile);
619        setPrimaryInvalid(lSkipsFile);
620      }
621    }
622
623    if (writeSkips.isSelected())
624    {
625      String skipPath = skipsFile.getText();
626      if (skipPath == null || "".equals(skipPath.trim()))
627      {
628        errors.add(ERR_CTRL_PANEL_SKIPS_FILE_REQUIRED.get());
629        setPrimaryInvalid(lSkipsFile);
630      }
631    }
632
633    updateIncludeExclude(errors, backendName);
634
635    if (errors.isEmpty())
636    {
637      ProgressDialog progressDialog = new ProgressDialog(
638          Utilities.createFrame(),
639          Utilities.getParentDialog(this), getTitle(), getInfo());
640      ImportTask newTask = new ImportTask(getInfo(), progressDialog);
641      for (Task task : getInfo().getTasks())
642      {
643        task.canLaunch(newTask, errors);
644      }
645      boolean confirmed = true;
646      boolean initializeAll = false;
647      if (errors.isEmpty())
648      {
649        Set<DN> replicatedBaseDNs = getReplicatedBaseDNs();
650        boolean canInitialize =
651          !replicatedBaseDNs.isEmpty() && isServerRunning();
652        if (overwrite.isSelected() && !canInitialize)
653        {
654          confirmed = displayConfirmationDialog(
655              INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(),
656              INFO_CTRL_PANEL_CONFIRMATION_IMPORT_LDIF_DETAILS.get(
657                  backendName));
658        }
659        else if (!overwrite.isSelected() && canInitialize)
660        {
661          ArrayList<String> dns = new ArrayList<>();
662          for (DN dn : replicatedBaseDNs)
663          {
664            dns.add(dn.toString());
665          }
666          initializeAll = displayConfirmationDialog(
667              INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(),
668              INFO_CTRL_PANEL_CONFIRMATION_INITIALIZE_ALL_DETAILS.get(
669                  Utilities.getStringFromCollection(dns, "<br>")));
670        }
671        else if (overwrite.isSelected() && canInitialize)
672        {
673          ArrayList<String> dns = new ArrayList<>();
674          for (DN dn : replicatedBaseDNs)
675          {
676            dns.add(dn.toString());
677          }
678          ConfirmInitializeAndImportDialog dlg =
679            new ConfirmInitializeAndImportDialog(
680                Utilities.getParentDialog(this), getInfo());
681          dlg.setMessage(INFO_CTRL_PANEL_CONFIRM_INITIALIZE_TITLE.get(),
682          INFO_CTRL_PANEL_CONFIRMATION_INITIALIZE_ALL_AND_OVERWRITE_DETAILS.get(
683                  backendName, Utilities.getStringFromCollection(dns, "<br>")));
684          dlg.setModal(true);
685          dlg.setVisible(true);
686
687          ConfirmInitializeAndImportDialog.Result result = dlg.getResult();
688          switch (result)
689          {
690          case CANCEL:
691            confirmed = false;
692            break;
693          case INITIALIZE_ALL:
694            confirmed = true;
695            initializeAll = true;
696            break;
697          case IMPORT_ONLY:
698            confirmed = true;
699            initializeAll = false;
700            break;
701            default:
702              throw new RuntimeException("Unexpected result: "+result);
703          }
704        }
705      }
706      if (errors.isEmpty() && confirmed)
707      {
708        newTask.setInitializeAll(initializeAll);
709        launchOperation(newTask,
710            INFO_CTRL_PANEL_IMPORTING_LDIF_SUMMARY.get(backends.getSelectedItem()),
711            INFO_CTRL_PANEL_IMPORTING_LDIF_SUCCESSFUL_SUMMARY.get(),
712            INFO_CTRL_PANEL_IMPORTING_LDIF_SUCCESSFUL_DETAILS.get(),
713            ERR_CTRL_PANEL_IMPORTING_LDIF_ERROR_SUMMARY.get(),
714            null,
715            ERR_CTRL_PANEL_IMPORTING_LDIF_ERROR_DETAILS,
716            progressDialog);
717        progressDialog.setVisible(true);
718        Utilities.getParentDialog(this).setVisible(false);
719      }
720    }
721    if (!errors.isEmpty())
722    {
723      displayErrorDialog(errors);
724    }
725  }
726
727  /** {@inheritDoc} */
728  @Override
729  public void cancelClicked()
730  {
731    setPrimaryValid(lBackend);
732    setPrimaryValid(lFile);
733    setPrimaryValid(lImportType);
734    setPrimaryValid(lSchemaValidation);
735    setPrimaryValid(lDNValidation);
736    setPrimaryValid(lThreads);
737    setPrimaryValid(lRejectsFile);
738    setPrimaryValid(lSkipsFile);
739    super.cancelClicked();
740  }
741
742  private Set<DN> getReplicatedBaseDNs()
743  {
744    Set<DN> baseDNs = new TreeSet<>();
745    String backendID = (String)backends.getSelectedItem();
746    if (backendID != null)
747    {
748      for (BackendDescriptor backend :
749        getInfo().getServerDescriptor().getBackends())
750      {
751        if (backendID.equalsIgnoreCase(backend.getBackendID()))
752        {
753          for (BaseDNDescriptor baseDN : backend.getBaseDns())
754          {
755            if (baseDN.getReplicaID() != -1)
756            {
757              baseDNs.add(baseDN.getDn());
758            }
759          }
760        }
761      }
762    }
763    return baseDNs;
764  }
765
766  /**
767   * The class that performs the import.
768   *
769   */
770  protected class ImportTask extends InclusionExclusionTask
771  {
772    private Set<String> backendSet;
773    private String fileName;
774    private boolean initializeAll;
775    private Set<DN> replicatedBaseDNs;
776
777    /**
778     * The constructor of the task.
779     * @param info the control panel info.
780     * @param dlg the progress dialog that shows the progress of the task.
781     */
782    public ImportTask(ControlPanelInfo info, ProgressDialog dlg)
783    {
784      super(info, dlg);
785      backendSet = new HashSet<>();
786      backendSet.add((String)backends.getSelectedItem());
787      fileName = file.getText();
788      replicatedBaseDNs = getReplicatedBaseDNs();
789    }
790
791    private void setInitializeAll(boolean initializeAll)
792    {
793      this.initializeAll = initializeAll;
794    }
795
796    /** {@inheritDoc} */
797    @Override
798    public Type getType()
799    {
800      return Type.IMPORT_LDIF;
801    }
802
803
804    /** {@inheritDoc} */
805    @Override
806    public LocalizableMessage getTaskDescription()
807    {
808      return INFO_CTRL_PANEL_IMPORT_TASK_DESCRIPTION.get(fileName,
809          backendSet.iterator().next());
810    }
811
812    /** {@inheritDoc} */
813    @Override
814    public boolean canLaunch(Task taskToBeLaunched,
815        Collection<LocalizableMessage> incompatibilityReasons)
816    {
817      boolean canLaunch = true;
818      if (state == State.RUNNING && runningOnSameServer(taskToBeLaunched))
819      {
820        // All the operations are incompatible if they apply to this backend.
821        Set<String> backends = new TreeSet<>(taskToBeLaunched.getBackends());
822        backends.retainAll(getBackends());
823        if (!backends.isEmpty())
824        {
825          incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched));
826          canLaunch = false;
827        }
828      }
829      return canLaunch;
830    }
831
832    /** {@inheritDoc} */
833    @Override
834    protected ArrayList<String> getCommandLineArguments()
835    {
836      ArrayList<String> args = new ArrayList<>();
837      args.add("--ldifFile");
838      args.add(fileName);
839      args.add("--backendID");
840      args.add((String)backends.getSelectedItem());
841      if (dataCompressed.isSelected())
842      {
843        args.add("--isCompressed");
844      }
845      if (overwrite.isSelected())
846      {
847        args.add("--clearBackend");
848      }
849      if (append.isSelected())
850      {
851        args.add("--append");
852        if (replaceEntries.isSelected())
853        {
854          args.add("--replaceExisting");
855        }
856      }
857      if (!rejectNotSchemaCompliant.isSelected())
858      {
859        args.add("--skipSchemaValidation");
860      }
861      if (doDNValidationAfter.isSelected())
862      {
863        args.add("--skipDNValidation");
864      }
865
866      String sThread = threads.getText().trim();
867      if (sThread.length() > 0)
868      {
869        args.add("--threadCount");
870        args.add(sThread);
871      }
872
873      if (writeRejects.isSelected())
874      {
875        args.add("--rejectFile");
876        args.add(rejectsFile.getText());
877      }
878
879      if (writeSkips.isSelected())
880      {
881        args.add("--skipFile");
882        args.add(skipsFile.getText());
883      }
884
885      if ((writeRejects.isSelected() || writeSkips.isSelected()) &&
886          overwriteRejectsFile.isSelected())
887      {
888        args.add("--overwrite");
889      }
890
891      args.addAll(super.getCommandLineArguments());
892
893      if (isServerRunning())
894      {
895        args.addAll(getConfigCommandLineArguments());
896      }
897
898      args.add(getNoPropertiesFileArgument());
899
900      return args;
901    }
902
903    /** {@inheritDoc} */
904    @Override
905    protected String getCommandLinePath()
906    {
907      return getCommandLinePath("import-ldif");
908    }
909
910    /** {@inheritDoc} */
911    @Override
912    public void runTask()
913    {
914      state = State.RUNNING;
915      lastException = null;
916      try
917      {
918        ArrayList<String> arguments = getCommandLineArguments();
919
920        String[] args = new String[arguments.size()];
921
922        arguments.toArray(args);
923        if (isServerRunning())
924        {
925          returnCode = ImportLDIF.mainImportLDIF(args, false, outPrintStream,
926              errorPrintStream);
927          if (returnCode == 0 && initializeAll)
928          {
929            initializeAll();
930          }
931        }
932        else
933        {
934          returnCode = executeCommandLine(getCommandLinePath(), args);
935        }
936        if (returnCode != 0)
937        {
938          state = State.FINISHED_WITH_ERROR;
939        }
940        else
941        {
942          for (String backend : getBackends())
943          {
944            getInfo().unregisterModifiedIndexesInBackend(backend);
945          }
946          state = State.FINISHED_SUCCESSFULLY;
947        }
948      }
949      catch (Throwable t)
950      {
951        lastException = t;
952        state = State.FINISHED_WITH_ERROR;
953      }
954      HashSet<BackendDescriptor> backends = new HashSet<>();
955      for (BackendDescriptor backend :
956        getInfo().getServerDescriptor().getBackends())
957      {
958        for (String backendID : getBackends())
959        {
960          if (backendID.equalsIgnoreCase(backend.getBackendID()))
961          {
962            backends.add(backend);
963            break;
964          }
965        }
966      }
967      if (!backends.isEmpty())
968      {
969        getInfo().backendPopulated(backends);
970      }
971    }
972
973    /** {@inheritDoc} */
974    @Override
975    public Set<String> getBackends()
976    {
977      return backendSet;
978    }
979
980    private void initializeAll() throws ReplicationCliException
981    {
982      ReplicationCliMain repl = new ReplicationCliMain(outPrintStream, errorPrintStream);
983      getProgressDialog().appendProgressHtml(
984          UIFactory.HTML_SEPARATOR+"<br><br>");
985
986      String cmd = getCommandLineToInitializeAll();
987
988      getProgressDialog().appendProgressHtml(Utilities.applyFont(
989          INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_INITIALIZE_ALL.get()+
990          "<br><b>"+cmd+"</b><br><br>",
991          ColorAndFontConstants.progressFont));
992
993      for (DN baseDN : replicatedBaseDNs)
994      {
995        LocalizableMessage msg = INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN,
996            ConnectionUtils.getHostPort(getInfo().getDirContext()));
997        getProgressDialog().appendProgressHtml(Utilities.applyFont(
998            msg + "<br>", ColorAndFontConstants.progressFont));
999        repl.initializeAllSuffix(baseDN.toString(), getInfo().getDirContext(), true);
1000      }
1001    }
1002
1003    private String getCommandLineToInitializeAll()
1004    {
1005      String cmdLineName = getCommandLinePath("dsreplication");
1006      ArrayList<String> args = new ArrayList<>();
1007      args.add(
1008          ReplicationCliArgumentParser.INITIALIZE_ALL_REPLICATION_SUBCMD_NAME);
1009      args.add("--hostName");
1010      args.add(getInfo().getServerDescriptor().getHostname());
1011      args.add("--port");
1012      args.add(String.valueOf(
1013          ConnectionUtils.getPort(getInfo().getDirContext())));
1014      for (DN baseDN : replicatedBaseDNs)
1015      {
1016        args.add("--baseDN");
1017        args.add(baseDN.toString());
1018      }
1019      args.add("--adminUID");
1020      args.add("admin");
1021      args.add("--adminPassword");
1022      args.add(OBFUSCATED_VALUE);
1023      args.add("--trustAll");
1024      args.add("--no-prompt");
1025
1026      return Task.getEquivalentCommandLine(cmdLineName, args);
1027    }
1028  }
1029}