001/*
002 * Copyright 2008-2024 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2008-2024 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2008-2024 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.ldap.sdk.unboundidds.tasks;
037
038
039
040import java.util.ArrayList;
041import java.util.Arrays;
042import java.util.Collections;
043import java.util.Date;
044import java.util.LinkedHashMap;
045import java.util.List;
046import java.util.Map;
047
048import com.unboundid.ldap.sdk.Attribute;
049import com.unboundid.ldap.sdk.Entry;
050import com.unboundid.util.Debug;
051import com.unboundid.util.NotMutable;
052import com.unboundid.util.NotNull;
053import com.unboundid.util.Nullable;
054import com.unboundid.util.StaticUtils;
055import com.unboundid.util.ThreadSafety;
056import com.unboundid.util.ThreadSafetyLevel;
057import com.unboundid.util.Validator;
058
059import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*;
060
061
062
063/**
064 * This class defines a Directory Server task that can be used to export the
065 * contents of a backend to LDIF.
066 * <BR>
067 * <BLOCKQUOTE>
068 *   <B>NOTE:</B>  This class, and other classes within the
069 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
070 *   supported for use against Ping Identity, UnboundID, and
071 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
072 *   for proprietary functionality or for external specifications that are not
073 *   considered stable or mature enough to be guaranteed to work in an
074 *   interoperable way with other types of LDAP servers.
075 * </BLOCKQUOTE>
076 * <BR>
077 * The properties that are available for use with this type of task include:
078 * <UL>
079 *   <LI>The backend ID for the backend from which the data is to be exported.
080 *       It must be provided when scheduling a task of this type.</LI>
081 *   <LI>The path (on the server system) and name of the LDIF file to be
082 *       written.  It must be provided when scheduling a task of this type.</LI>
083 *   <LI>A flag that indicates whether to append to any existing file or to
084 *       overwrite it.</LI>
085 *   <LI>An optional list of base DNs for branches that should be included in
086 *       the export.</LI>
087 *   <LI>An optional list of base DNs for branches that should be excluded from
088 *       the export.</LI>
089 *   <LI>An optional list of filters that may be used to determine whether an
090 *       entry should be included in the export.</LI>
091 *   <LI>An optional list of filters that may be used to determine whether an
092 *       entry should be excluded from the export.</LI>
093 *   <LI>An optional list of attributes that should be included in entries that
094 *       are exported.</LI>
095 *   <LI>An optional list of attributes that should be excluded form entries
096 *       that are exported.</LI>
097 *   <LI>An integer value that specifies the column at which long lines should
098 *       be wrapped.  A value less than or equal to zero indicates that no
099 *       wrapping should be performed.</LI>
100 *   <LI>A flag that indicates whether to compress the LDIF data as it is
101 *       written.</LI>
102 *   <LI>A flag that indicates whether to encrypt the LDIF data as it is
103 *       written.</LI>
104 *   <LI>A flag that indicates whether to generate a signature for the LDIF data
105 *       as it is written.</LI>
106 *   <LI>The path to a file containing a passphrase to use to generate the
107 *       encryption key.</LI>
108 *   <LI>The ID of the encryption settings definition to use to generate the
109 *       encryption key.</LI>
110 *   <LI>The maximum rate in megabytes per second at which the LDIF file should
111 *       be written.</LI>
112 * </UL>
113 */
114@NotMutable()
115@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
116public final class ExportTask
117       extends Task
118{
119  /**
120   * The fully-qualified name of the Java class that is used for the export
121   * task.
122   */
123  @NotNull static final String EXPORT_TASK_CLASS =
124       "com.unboundid.directory.server.tasks.ExportTask";
125
126
127
128  /**
129   * The name of the attribute used to indicate whether to append to an existing
130   * file.
131   */
132  @NotNull private static final String ATTR_APPEND_TO_LDIF =
133       "ds-task-export-append-to-ldif";
134
135
136
137  /**
138   * The name of the attribute used to specify the backend ID of the backend to
139   * export.
140   */
141  @NotNull private static final String ATTR_BACKEND_ID =
142       "ds-task-export-backend-id";
143
144
145
146  /**
147   * The name of the attribute used to indicate whether the exported LDIF should
148   * be compressed as it is written.
149   */
150  @NotNull private static final String ATTR_COMPRESS =
151       "ds-task-export-compress-ldif";
152
153
154
155  /**
156   * The name of the attribute used to indicate whether the exported LDIF should
157   * be encrypted as it is written.
158   */
159  @NotNull private static final String ATTR_ENCRYPT =
160       "ds-task-export-encrypt-ldif";
161
162
163
164  /**
165   * The name of the attribute used to specify the path to a file that contains
166   * the passphrase to use to generate the encryption key.
167   */
168  @NotNull private static final String ATTR_ENCRYPTION_PASSPHRASE_FILE =
169       "ds-task-export-encryption-passphrase-file";
170
171
172
173  /**
174   * The name of the attribute used to specify the path to a file that contains
175   * the ID of the encryption settings definition to use to generate the
176   * encryption key.
177   */
178  @NotNull private static final String ATTR_ENCRYPTION_SETTINGS_DEFINITION_ID =
179       "ds-task-export-encryption-settings-definition-id";
180
181
182
183  /**
184   * The name of the attribute used to specify the attributes to exclude from
185   * the export.
186   */
187  @NotNull private static final String ATTR_EXCLUDE_ATTRIBUTE =
188       "ds-task-export-exclude-attribute";
189
190
191
192  /**
193   * The name of the attribute used to specify the base DNs to exclude from the
194   * export.
195   */
196  @NotNull private static final String ATTR_EXCLUDE_BRANCH =
197       "ds-task-export-exclude-branch";
198
199
200
201  /**
202   * The name of the attribute used to specify the filters to use to identify
203   * entries to exclude from the export.
204   */
205  @NotNull private static final String ATTR_EXCLUDE_FILTER =
206       "ds-task-export-exclude-filter";
207
208
209
210  /**
211   * The name of the attribute used to specify the attributes to include in the
212   * export.
213   */
214  @NotNull private static final String ATTR_INCLUDE_ATTRIBUTE =
215       "ds-task-export-include-attribute";
216
217
218
219  /**
220   * The name of the attribute used to specify the base DNs to include in the
221   * export.
222   */
223  @NotNull private static final String ATTR_INCLUDE_BRANCH =
224       "ds-task-export-include-branch";
225
226
227
228  /**
229   * The name of the attribute used to specify the filters to use to identify
230   * entries to include in the export.
231   */
232  @NotNull private static final String ATTR_INCLUDE_FILTER =
233       "ds-task-export-include-filter";
234
235
236
237  /**
238   * The name of the attribute used to specify the path to the LDIF file to be
239   * written.
240   */
241  @NotNull private static final String ATTR_LDIF_FILE =
242       "ds-task-export-ldif-file";
243
244
245
246  /**
247   * The name of the attribute used to specify the maximum LDIF write rate in
248   * megabytes per second.
249   */
250  @NotNull private static final String ATTR_MAX_MEGABYTES_PER_SECOND =
251       "ds-task-export-max-megabytes-per-second";
252
253
254
255  /**
256   * The name of the attribute used to specify the names or DNs of the
257   * post-LDIF-export task processors to invoke when the export completes.
258   */
259  @NotNull private static final String ATTR_POST_EXPORT_PROCESSOR =
260       "ds-task-export-post-export-processor";
261
262
263
264  /**
265   * The name of the attribute used to indicate whether the exported LDIF should
266   * include a signed hash of the contents.
267   */
268  @NotNull private static final String ATTR_SIGN = "ds-task-export-sign-hash";
269
270
271
272  /**
273   * The name of the attribute used to specify the column at which to wrap long
274   * lines in the export.
275   */
276  @NotNull private static final String ATTR_WRAP_COLUMN =
277       "ds-task-export-wrap-column";
278
279
280
281  /**
282   * The name of the object class used in export task entries.
283   */
284  @NotNull private static final String OC_EXPORT_TASK = "ds-task-export";
285
286
287
288  /**
289   * The task property for the backend ID.
290   */
291  @NotNull private static final TaskProperty PROPERTY_BACKEND_ID =
292       new TaskProperty(ATTR_BACKEND_ID, INFO_DISPLAY_NAME_BACKEND_ID.get(),
293                        INFO_DESCRIPTION_BACKEND_ID_EXPORT.get(), String.class,
294                        true, false, false);
295
296
297
298  /**
299   * The task property for the LDIF file.
300   */
301  @NotNull private static final TaskProperty PROPERTY_LDIF_FILE =
302       new TaskProperty(ATTR_LDIF_FILE, INFO_DISPLAY_NAME_LDIF_FILE.get(),
303                        INFO_DESCRIPTION_LDIF_FILE_EXPORT.get(), String.class,
304                        true, false, false);
305
306
307
308  /**
309   * The task property for the append to LDIF flag.
310   */
311  @NotNull private static final TaskProperty PROPERTY_APPEND_TO_LDIF =
312       new TaskProperty(ATTR_APPEND_TO_LDIF,
313                        INFO_DISPLAY_NAME_APPEND_TO_LDIF.get(),
314                        INFO_DESCRIPTION_APPEND_TO_LDIF.get(), Boolean.class,
315                        false, false, true);
316
317
318
319  /**
320   * The task property for the include branches.
321   */
322  @NotNull private static final TaskProperty PROPERTY_INCLUDE_BRANCH =
323       new TaskProperty(ATTR_INCLUDE_BRANCH,
324                        INFO_DISPLAY_NAME_INCLUDE_BRANCH.get(),
325                        INFO_DESCRIPTION_INCLUDE_BRANCH_EXPORT.get(),
326                        String.class, false, true, true);
327
328
329
330  /**
331   * The task property for the exclude branches.
332   */
333  @NotNull private static final TaskProperty PROPERTY_EXCLUDE_BRANCH =
334       new TaskProperty(ATTR_EXCLUDE_BRANCH,
335                        INFO_DISPLAY_NAME_EXCLUDE_BRANCH.get(),
336                        INFO_DESCRIPTION_EXCLUDE_BRANCH_EXPORT.get(),
337                        String.class, false, true, true);
338
339
340
341  /**
342   * The task property for the include filters.
343   */
344  @NotNull private static final TaskProperty PROPERTY_INCLUDE_FILTER =
345       new TaskProperty(ATTR_INCLUDE_FILTER,
346                        INFO_DISPLAY_NAME_INCLUDE_FILTER.get(),
347                        INFO_DESCRIPTION_INCLUDE_FILTER_EXPORT.get(),
348                        String.class, false, true, true);
349
350
351
352  /**
353   * The task property for the exclude filters.
354   */
355  @NotNull private static final TaskProperty PROPERTY_EXCLUDE_FILTER =
356       new TaskProperty(ATTR_EXCLUDE_FILTER,
357                        INFO_DISPLAY_NAME_EXCLUDE_FILTER.get(),
358                        INFO_DESCRIPTION_EXCLUDE_FILTER_EXPORT.get(),
359                        String.class, false, true, true);
360
361
362
363  /**
364   * The task property for the include attributes.
365   */
366  @NotNull private static final TaskProperty PROPERTY_INCLUDE_ATTRIBUTE =
367       new TaskProperty(ATTR_INCLUDE_ATTRIBUTE,
368                        INFO_DISPLAY_NAME_INCLUDE_ATTRIBUTE.get(),
369                        INFO_DESCRIPTION_INCLUDE_ATTRIBUTE_EXPORT.get(),
370                        String.class, false, true, true);
371
372
373
374  /**
375   * The task property for the exclude attributes.
376   */
377  @NotNull private static final TaskProperty PROPERTY_EXCLUDE_ATTRIBUTE =
378       new TaskProperty(ATTR_EXCLUDE_ATTRIBUTE,
379                        INFO_DISPLAY_NAME_EXCLUDE_ATTRIBUTE.get(),
380                        INFO_DESCRIPTION_EXCLUDE_ATTRIBUTE_EXPORT.get(),
381                        String.class, false, true, true);
382
383
384
385  /**
386   * The task property for the wrap column.
387   */
388  @NotNull private static final TaskProperty PROPERTY_WRAP_COLUMN =
389       new TaskProperty(ATTR_WRAP_COLUMN, INFO_DISPLAY_NAME_WRAP_COLUMN.get(),
390                        INFO_DESCRIPTION_WRAP_COLUMN.get(), Long.class, false,
391                        false, true);
392
393
394
395  /**
396   * The task property for the compress flag.
397   */
398  @NotNull private static final TaskProperty PROPERTY_COMPRESS =
399       new TaskProperty(ATTR_COMPRESS, INFO_DISPLAY_NAME_COMPRESS.get(),
400                        INFO_DESCRIPTION_COMPRESS_EXPORT.get(), Boolean.class,
401                        false, false, false);
402
403
404
405  /**
406   * The task property for the encrypt flag.
407   */
408  @NotNull private static final TaskProperty PROPERTY_ENCRYPT =
409       new TaskProperty(ATTR_ENCRYPT, INFO_DISPLAY_NAME_ENCRYPT.get(),
410                        INFO_DESCRIPTION_ENCRYPT_EXPORT.get(), Boolean.class,
411                        false, false, false);
412
413
414
415  /**
416   * The task property that will be used for the encryption passphrase file.
417   */
418  @NotNull private static final TaskProperty
419       PROPERTY_ENCRYPTION_PASSPHRASE_FILE = new TaskProperty(
420            ATTR_ENCRYPTION_PASSPHRASE_FILE,
421            INFO_DISPLAY_NAME_ENCRYPTION_PASSPHRASE_FILE.get(),
422            INFO_DESCRIPTION_ENCRYPTION_PASSPHRASE_FILE.get(),
423            String.class, false, false, true);
424
425
426
427  /**
428   * The task property that will be used for the encryption settings definition
429   * ID.
430   */
431  @NotNull private static final TaskProperty
432       PROPERTY_ENCRYPTION_SETTINGS_DEFINITION_ID = new TaskProperty(
433            ATTR_ENCRYPTION_SETTINGS_DEFINITION_ID,
434            INFO_DISPLAY_NAME_ENCRYPTION_SETTINGS_DEFINITION_ID.get(),
435            INFO_DESCRIPTION_ENCRYPTION_SETTINGS_DEFINITION_ID.get(),
436            String.class, false, false, true);
437
438
439
440  /**
441   * The task property for the sign flag.
442   */
443  @NotNull private static final TaskProperty PROPERTY_SIGN =
444       new TaskProperty(ATTR_SIGN, INFO_DISPLAY_NAME_SIGN.get(),
445                        INFO_DESCRIPTION_SIGN_EXPORT.get(), Boolean.class,
446                        false, false, false);
447
448
449
450  /**
451   * The task property that will be used for the maximum write rate in megabytes
452   * per second.
453   */
454  @NotNull private static final TaskProperty PROPERTY_MAX_MEGABYTES_PER_SECOND =
455       new TaskProperty(ATTR_MAX_MEGABYTES_PER_SECOND,
456            INFO_DISPLAY_NAME_EXPORT_MAX_MEGABYTES_PER_SECOND.get(),
457            INFO_DESCRIPTION_EXPORT_MAX_MEGABYTES_PER_SECOND.get(),
458            Long.class, false, false, true);
459
460
461
462  /**
463   * The task property that will be used for the set of post-LDIF-export task
464   * processors to invoke after the export complets.
465   */
466  @NotNull private static final TaskProperty PROPERTY_POST_EXPORT_PROCESSOR =
467       new TaskProperty(ATTR_POST_EXPORT_PROCESSOR,
468            INFO_DISPLAY_NAME_POST_EXPORT_PROCESSOR.get(),
469            INFO_DESCRIPTION_POST_EXPORT_PROCESSOR.get(),
470            String.class, false, true, true);
471
472
473
474  /**
475   * The serial version UID for this serializable class.
476   */
477  private static final long serialVersionUID = -6807534587873728959L;
478
479
480
481  // Indicates whether to append the data to an existing file.
482  private final boolean appendToLDIF;
483
484  // Indicates whether to compress the data.
485  private final boolean compress;
486
487  // Indicates whether to encrypt the data.
488  private final boolean encrypt;
489
490  // Indicates whether to sign the data.
491  private final boolean sign;
492
493  // The column at which to wrap long lines.
494  private final int wrapColumn;
495
496  // The maximum write rate in megabytes per second.
497  @Nullable private final Integer maxMegabytesPerSecond;
498
499  // The set of attributes to exclude from the export.
500  @NotNull private final List<String> excludeAttributes;
501
502  // The set of base DNs to exclude from the export.
503  @NotNull private final List<String> excludeBranches;
504
505  // The set of filters to use to identify entries to exclude.
506  @NotNull private final List<String> excludeFilters;
507
508  // The set of attributes to include in the export.
509  @NotNull private final List<String> includeAttributes;
510
511  // The set of base DNs to include in the export.
512  @NotNull private final List<String> includeBranches;
513
514  // The set of filters to use to identify entries to include.
515  @NotNull private final List<String> includeFilters;
516
517  // The set of post-LDIF-export task processors to invoke after the export
518  // completes.
519  @NotNull private final List<String> postExportTaskProcessors;
520
521  // The backend ID of the backend to export.
522  @NotNull private final String backendID;
523
524  // The path to a file containing the passphrase to use to generate the
525  // encryption key.
526  @Nullable private final String encryptionPassphraseFile;
527
528  // The identifier for the encryption settings definition to use to generate
529  // the encryption key.
530  @Nullable private final String encryptionSettingsDefinitionID;
531
532  // The path to the LDIF file to generate.
533  @NotNull private final String ldifFile;
534
535
536
537  /**
538   * Creates a new uninitialized export task instance which should only be used
539   * for obtaining general information about this task, including the task name,
540   * description, and supported properties.  Attempts to use a task created with
541   * this constructor for any other reason will likely fail.
542   */
543  public ExportTask()
544  {
545    appendToLDIF = false;
546    compress = false;
547    encrypt = false;
548    sign = false;
549    wrapColumn = -1;
550    maxMegabytesPerSecond = null;
551    encryptionPassphraseFile = null;
552    encryptionSettingsDefinitionID = null;
553    excludeAttributes = null;
554    excludeBranches = null;
555    excludeFilters = null;
556    includeAttributes = null;
557    includeBranches = null;
558    includeFilters = null;
559    postExportTaskProcessors = null;
560    backendID = null;
561    ldifFile = null;
562  }
563
564
565
566  /**
567   * Creates a new export task with the provided information.
568   *
569   * @param  taskID     The task ID to use for this task.  If it is {@code null}
570   *                    then a UUID will be generated for use as the task ID.
571   * @param  backendID  The backend ID of the backend containing the data to
572   *                    export.  It must not be {@code null}.
573   * @param  ldifFile   The path to the LDIF file to create.  It may be an
574   *                    absolute path or a path relative to the server install
575   *                    root.  It must not be {@code null}.
576   */
577  public ExportTask(@Nullable final String taskID,
578                    @NotNull final String backendID,
579                    @NotNull final String ldifFile)
580  {
581    this(taskID, backendID, ldifFile, false, null, null, null, null, null, null,
582         -1, false, false, false, null, null, null, null, null);
583  }
584
585
586
587  /**
588   * Creates a new export task with the provided information.
589   *
590   * @param  taskID                  The task ID to use for this task.  If it is
591   *                                 {@code null} then a UUID will be generated
592   *                                 for use as the task ID.
593   * @param  backendID               The backend ID of the backend to be
594   *                                 exported.  It must not be {@code null}.
595   * @param  ldifFile                The path to the LDIF file to be written.
596   *                                 It may be an absolute path or one that is
597   *                                 relative to the server root.  It must not
598   *                                 be {@code null}.
599   * @param  appendToLDIF            Indicates whether to an append to any
600   *                                 existing file rather than overwriting it.
601   * @param  includeBranches         The set of base DNs of entries to include
602   *                                 in the export.  It may be {@code null} or
603   *                                 empty if no entries should be excluded
604   *                                 based on their location.
605   * @param  excludeBranches         The set of base DNs of entries to exclude
606   *                                 from the export.  It may be {@code null} or
607   *                                 empty if no entries should be excluded
608   *                                 based on their location.
609   * @param  includeFilters          The set of filters to use to match entries
610   *                                 that should be included in the export.  It
611   *                                 may be {@code null} or empty if no entries
612   *                                 should be excluded based on their content.
613   * @param  excludeFilters          The set of filters to use to match entries
614   *                                 that should be excluded from the export.
615   *                                 It may be {@code null} or empty if no
616   *                                 entries should be excluded based on their
617   *                                 content.
618   * @param  includeAttributes       The set of attributes that should be
619   *                                 included in exported entries.  It may be
620   *                                 {@code null} or empty if all attributes
621   *                                 should be included.
622   * @param  excludeAttributes       The set of attributes that should be
623   *                                 excluded from exported entries.  It may be
624   *                                 {@code null} or empty if no attributes
625   *                                 should be excluded.
626   * @param  wrapColumn              The column at which long lines should be
627   *                                 wrapped.  It may be less than or equal to
628   *                                 zero to indicate that long lines should not
629   *                                 be wrapped.
630   * @param  compress                Indicates whether the LDIF data should be
631   *                                 compressed as it is written.
632   * @param  encrypt                 Indicates whether the LDIF data should be
633   *                                 encrypted as it is written.
634   * @param  sign                    Indicates whether to include a signed hash
635   *                                 of the content in the exported data.
636   * @param  scheduledStartTime      The time that this task should start
637   *                                 running.
638   * @param  dependencyIDs           The list of task IDs that will be required
639   *                                 to complete before this task will be
640   *                                 eligible to start.
641   * @param  failedDependencyAction  Indicates what action should be taken if
642   *                                 any of the dependencies for this task do
643   *                                 not complete successfully.
644   * @param  notifyOnCompletion      The list of e-mail addresses of individuals
645   *                                 that should be notified when this task
646   *                                 completes.
647   * @param  notifyOnError           The list of e-mail addresses of individuals
648   *                                 that should be notified if this task does
649   *                                 not complete successfully.
650   */
651  public ExportTask(@Nullable final String taskID,
652              @NotNull final String backendID,
653              @NotNull final String ldifFile,
654              final boolean appendToLDIF,
655              @Nullable final List<String> includeBranches,
656              @Nullable final List<String> excludeBranches,
657              @Nullable final List<String> includeFilters,
658              @Nullable final List<String> excludeFilters,
659              @Nullable final List<String> includeAttributes,
660              @Nullable final List<String> excludeAttributes,
661              final int wrapColumn,
662              final boolean compress,
663              final boolean encrypt,
664              final boolean sign,
665              @Nullable final Date scheduledStartTime,
666              @Nullable final List<String> dependencyIDs,
667              @Nullable final FailedDependencyAction failedDependencyAction,
668              @Nullable final List<String> notifyOnCompletion,
669              @Nullable final List<String> notifyOnError)
670  {
671    this(taskID, backendID, ldifFile, appendToLDIF, includeBranches,
672         excludeBranches, includeFilters, excludeFilters, includeAttributes,
673         excludeAttributes, wrapColumn, compress, encrypt, null, null, sign,
674         null, scheduledStartTime, dependencyIDs, failedDependencyAction,
675         notifyOnCompletion, notifyOnError);
676  }
677
678
679
680  /**
681   * Creates a new export task with the provided information.
682   *
683   * @param  taskID                          The task ID to use for this task.
684   *                                         If it is {@code null} then a UUID
685   *                                         will be generated for use as the
686   *                                         task ID.
687   * @param  backendID                       The backend ID of the backend to be
688   *                                         exported.  It must not be
689   *                                         {@code null}.
690   * @param  ldifFile                        The path to the LDIF file to be
691   *                                         written.  It may be an absolute
692   *                                         path or one that is relative to the
693   *                                         server root.  It must not be
694   *                                         {@code null}.
695   * @param  appendToLDIF                    Indicates whether to an append to
696   *                                         any existing file rather than
697   *                                         overwriting it.
698   * @param  includeBranches                 The set of base DNs of entries to
699   *                                         include in the export.  It may be
700   *                                         {@code null} or empty if no entries
701   *                                         should be excluded based on their
702   *                                         location.
703   * @param  excludeBranches                 The set of base DNs of entries to
704   *                                         exclude from the export.  It may be
705   *                                         {@code null} or empty if no entries
706   *                                         should be excluded based on their
707   *                                         location.
708   * @param  includeFilters                  The set of filters to use to match
709   *                                         entries that should be included in
710   *                                         the export.  It may be {@code null}
711   *                                         or empty if no entries should be
712   *                                         excluded based on their content.
713   * @param  excludeFilters                  The set of filters to use to match
714   *                                         entries that should be excluded
715   *                                         from the export.  It may be
716   *                                         {@code null} or empty if no entries
717   *                                         should be excluded based on their
718   *                                         content.
719   * @param  includeAttributes               The set of attributes that should
720   *                                         be included in exported entries.
721   *                                         It may be {@code null} or empty if
722   *                                         all attributes should be included.
723   * @param  excludeAttributes               The set of attributes that should
724   *                                         be excluded from exported entries.
725   *                                         It may be {@code null} or empty if
726   *                                         no attributes should be excluded.
727   * @param  wrapColumn                      The column at which long lines
728   *                                         should be wrapped.  It may be less
729   *                                         than or equal to zero to indicate
730   *                                         that long lines should not be
731   *                                         wrapped.
732   * @param  compress                        Indicates whether the LDIF data
733   *                                         should be compressed as it is
734   *                                         written.
735   * @param  encrypt                         Indicates whether the LDIF data
736   *                                         should be encrypted as it is
737   *                                         written.
738   * @param  encryptionPassphraseFile        The path to a file containing the
739   *                                         passphrase to use to generate the
740   *                                         encryption key.  It amy be
741   *                                         {@code null} if the LDIF file is
742   *                                         not to be encrypted, or if the key
743   *                                         should be obtained in some other
744   *                                         way.
745   * @param  encryptionSettingsDefinitionID  The ID of the encryption settings
746   *                                         definition use to generate the
747   *                                         encryption key.  It may be
748   *                                         {@code null} if the LDIF file is
749   *                                         not to be encrypted, or if the key
750   *                                         should be obtained in some other
751   *                                         way.
752   * @param  sign                            Indicates whether to include a
753   *                                         signed hash of the content in the
754   *                                         exported data.
755   * @param  maxMegabytesPerSecond           The maximum rate in megabytes per
756   *                                         second at which the LDIF file
757   *                                         should be written.
758   * @param  scheduledStartTime              The time that this task should
759   *                                         start running.
760   * @param  dependencyIDs                   The list of task IDs that will be
761   *                                         required to complete before this
762   *                                         task will be eligible to start.
763   * @param  failedDependencyAction          Indicates what action should be
764   *                                         taken if any of the dependencies
765   *                                         for this task do not complete
766   *                                         successfully.
767   * @param  notifyOnCompletion              The list of e-mail addresses of
768   *                                         individuals that should be notified
769   *                                         when this task completes.
770   * @param  notifyOnError                   The list of e-mail addresses of
771   *                                         individuals that should be notified
772   *                                         if this task does not complete
773   *                                         successfully.
774   */
775  public ExportTask(@Nullable final String taskID,
776              @NotNull final String backendID,
777              @NotNull final String ldifFile,
778              final boolean appendToLDIF,
779              @Nullable final List<String> includeBranches,
780              @Nullable final List<String> excludeBranches,
781              @Nullable final List<String> includeFilters,
782              @Nullable final List<String> excludeFilters,
783              @Nullable final List<String> includeAttributes,
784              @Nullable final List<String> excludeAttributes,
785              final int wrapColumn,
786              final boolean compress, final boolean encrypt,
787              @Nullable final String encryptionPassphraseFile,
788              @Nullable final String encryptionSettingsDefinitionID,
789              final boolean sign,
790              @Nullable final Integer maxMegabytesPerSecond,
791              @Nullable final Date scheduledStartTime,
792              @Nullable final List<String> dependencyIDs,
793              @Nullable final FailedDependencyAction failedDependencyAction,
794              @Nullable final List<String> notifyOnCompletion,
795              @Nullable final List<String> notifyOnError)
796  {
797    this(taskID, backendID, ldifFile, appendToLDIF, includeBranches,
798         excludeBranches, includeFilters, excludeFilters, includeAttributes,
799         excludeAttributes, wrapColumn, compress, encrypt,
800         encryptionPassphraseFile, encryptionSettingsDefinitionID, sign,
801         maxMegabytesPerSecond, scheduledStartTime, dependencyIDs,
802         failedDependencyAction, null, notifyOnCompletion, null,
803         notifyOnError, null, null, null);
804  }
805
806
807
808  /**
809   * Creates a new export task with the provided information.
810   *
811   * @param  taskID                          The task ID to use for this task.
812   *                                         If it is {@code null} then a UUID
813   *                                         will be generated for use as the
814   *                                         task ID.
815   * @param  backendID                       The backend ID of the backend to be
816   *                                         exported.  It must not be
817   *                                         {@code null}.
818   * @param  ldifFile                        The path to the LDIF file to be
819   *                                         written.  It may be an absolute
820   *                                         path or one that is relative to the
821   *                                         server root.  It must not be
822   *                                         {@code null}.
823   * @param  appendToLDIF                    Indicates whether to an append to
824   *                                         any existing file rather than
825   *                                         overwriting it.
826   * @param  includeBranches                 The set of base DNs of entries to
827   *                                         include in the export.  It may be
828   *                                         {@code null} or empty if no entries
829   *                                         should be excluded based on their
830   *                                         location.
831   * @param  excludeBranches                 The set of base DNs of entries to
832   *                                         exclude from the export.  It may be
833   *                                         {@code null} or empty if no entries
834   *                                         should be excluded based on their
835   *                                         location.
836   * @param  includeFilters                  The set of filters to use to match
837   *                                         entries that should be included in
838   *                                         the export.  It may be {@code null}
839   *                                         or empty if no entries should be
840   *                                         excluded based on their content.
841   * @param  excludeFilters                  The set of filters to use to match
842   *                                         entries that should be excluded
843   *                                         from the export.  It may be
844   *                                         {@code null} or empty if no entries
845   *                                         should be excluded based on their
846   *                                         content.
847   * @param  includeAttributes               The set of attributes that should
848   *                                         be included in exported entries.
849   *                                         It may be {@code null} or empty if
850   *                                         all attributes should be included.
851   * @param  excludeAttributes               The set of attributes that should
852   *                                         be excluded from exported entries.
853   *                                         It may be {@code null} or empty if
854   *                                         no attributes should be excluded.
855   * @param  wrapColumn                      The column at which long lines
856   *                                         should be wrapped.  It may be less
857   *                                         than or equal to zero to indicate
858   *                                         that long lines should not be
859   *                                         wrapped.
860   * @param  compress                        Indicates whether the LDIF data
861   *                                         should be compressed as it is
862   *                                         written.
863   * @param  encrypt                         Indicates whether the LDIF data
864   *                                         should be encrypted as it is
865   *                                         written.
866   * @param  encryptionPassphraseFile        The path to a file containing the
867   *                                         passphrase to use to generate the
868   *                                         encryption key.  It amy be
869   *                                         {@code null} if the LDIF file is
870   *                                         not to be encrypted, or if the key
871   *                                         should be obtained in some other
872   *                                         way.
873   * @param  encryptionSettingsDefinitionID  The ID of the encryption settings
874   *                                         definition use to generate the
875   *                                         encryption key.  It may be
876   *                                         {@code null} if the LDIF file is
877   *                                         not to be encrypted, or if the key
878   *                                         should be obtained in some other
879   *                                         way.
880   * @param  sign                            Indicates whether to include a
881   *                                         signed hash of the content in the
882   *                                         exported data.
883   * @param  maxMegabytesPerSecond           The maximum rate in megabytes per
884   *                                         second at which the LDIF file
885   *                                         should be written.
886   * @param  scheduledStartTime              The time that this task should
887   *                                         start running.
888   * @param  dependencyIDs                   The list of task IDs that will be
889   *                                         required to complete before this
890   *                                         task will be eligible to start.
891   * @param  failedDependencyAction          Indicates what action should be
892   *                                         taken if any of the dependencies
893   *                                         for this task do not complete
894   *                                         successfully.
895   * @param  notifyOnStart                   The list of e-mail addresses of
896   *                                         individuals that should be notified
897   *                                         when this task starts running.
898   * @param  notifyOnCompletion              The list of e-mail addresses of
899   *                                         individuals that should be notified
900   *                                         when this task completes.
901   * @param  notifyOnSuccess                 The list of e-mail addresses of
902   *                                         individuals that should be notified
903   *                                         if this task completes
904   *                                         successfully.
905   * @param  notifyOnError                   The list of e-mail addresses of
906   *                                         individuals that should be notified
907   *                                         if this task does not complete
908   *                                         successfully.
909   * @param  alertOnStart                    Indicates whether the server should
910   *                                         send an alert notification when
911   *                                         this task starts.
912   * @param  alertOnSuccess                  Indicates whether the server should
913   *                                         send an alert notification if this
914   *                                         task completes successfully.
915   * @param  alertOnError                    Indicates whether the server should
916   *                                         send an alert notification if this
917   *                                         task fails to complete
918   *                                         successfully.
919   */
920  public ExportTask(@Nullable final String taskID,
921              @NotNull final String backendID,
922              @NotNull final String ldifFile,
923              final boolean appendToLDIF,
924              @Nullable final List<String> includeBranches,
925              @Nullable final List<String> excludeBranches,
926              @Nullable final List<String> includeFilters,
927              @Nullable final List<String> excludeFilters,
928              @Nullable final List<String> includeAttributes,
929              @Nullable final List<String> excludeAttributes,
930              final int wrapColumn,
931              final boolean compress, final boolean encrypt,
932              @Nullable final String encryptionPassphraseFile,
933              @Nullable final String encryptionSettingsDefinitionID,
934              final boolean sign,
935              @Nullable final Integer maxMegabytesPerSecond,
936              @Nullable final Date scheduledStartTime,
937              @Nullable final List<String> dependencyIDs,
938              @Nullable final FailedDependencyAction failedDependencyAction,
939              @Nullable final List<String> notifyOnStart,
940              @Nullable final List<String> notifyOnCompletion,
941              @Nullable final List<String> notifyOnSuccess,
942              @Nullable final List<String> notifyOnError,
943              @Nullable final Boolean alertOnStart,
944              @Nullable final Boolean alertOnSuccess,
945              @Nullable final Boolean alertOnError)
946  {
947    super(taskID, EXPORT_TASK_CLASS, scheduledStartTime,
948         dependencyIDs, failedDependencyAction, notifyOnStart,
949         notifyOnCompletion, notifyOnSuccess, notifyOnError, alertOnStart,
950         alertOnSuccess, alertOnError);
951
952    Validator.ensureNotNull(backendID, ldifFile);
953
954    this.backendID = backendID;
955    this.ldifFile = ldifFile;
956    this.appendToLDIF = appendToLDIF;
957    this.wrapColumn = wrapColumn;
958    this.compress = compress;
959    this.encrypt = encrypt;
960    this.encryptionPassphraseFile = encryptionPassphraseFile;
961    this.encryptionSettingsDefinitionID = encryptionSettingsDefinitionID;
962    this.sign = sign;
963    this.maxMegabytesPerSecond = maxMegabytesPerSecond;
964
965    if (includeBranches == null)
966    {
967      this.includeBranches = Collections.emptyList();
968    }
969    else
970    {
971      this.includeBranches = Collections.unmodifiableList(includeBranches);
972    }
973
974    if (excludeBranches == null)
975    {
976      this.excludeBranches = Collections.emptyList();
977    }
978    else
979    {
980      this.excludeBranches = Collections.unmodifiableList(excludeBranches);
981    }
982
983    if (includeFilters == null)
984    {
985      this.includeFilters = Collections.emptyList();
986    }
987    else
988    {
989      this.includeFilters = Collections.unmodifiableList(includeFilters);
990    }
991
992    if (excludeFilters == null)
993    {
994      this.excludeFilters = Collections.emptyList();
995    }
996    else
997    {
998      this.excludeFilters = Collections.unmodifiableList(excludeFilters);
999    }
1000
1001    if (includeAttributes == null)
1002    {
1003      this.includeAttributes = Collections.emptyList();
1004    }
1005    else
1006    {
1007      this.includeAttributes = Collections.unmodifiableList(includeAttributes);
1008    }
1009
1010    if (excludeAttributes == null)
1011    {
1012      this.excludeAttributes = Collections.emptyList();
1013    }
1014    else
1015    {
1016      this.excludeAttributes = Collections.unmodifiableList(excludeAttributes);
1017    }
1018
1019    postExportTaskProcessors = new ArrayList<>();
1020  }
1021
1022
1023
1024  /**
1025   * Creates a new export task with the provided set of properties.
1026   *
1027   * @param  properties  The properties to use to create this LDIF export
1028   *                     task.
1029   */
1030  public ExportTask(@NotNull final ExportTaskProperties properties)
1031  {
1032    super(properties.getTaskID(), EXPORT_TASK_CLASS,
1033         properties.getScheduledStartTime(), properties.getDependencyIDs(),
1034         properties.getFailedDependencyAction(), properties.getNotifyOnStart(),
1035         properties.getNotifyOnCompletion(), properties.getNotifyOnSuccess(),
1036         properties.getNotifyOnError(), properties.getAlertOnStart(),
1037         properties.getAlertOnSuccess(), properties.getAlertOnError());
1038
1039    appendToLDIF = properties.appendToLDIF();
1040    compress = properties.compress();
1041    encrypt = properties.encrypt();
1042    sign = properties.sign();
1043    wrapColumn = properties.getWrapColumn();
1044    maxMegabytesPerSecond = properties.getMaxMegabytesPerSecond();
1045    excludeAttributes = Collections.unmodifiableList(
1046         new ArrayList<>(properties.getExcludeAttributes()));
1047    excludeBranches = Collections.unmodifiableList(
1048         new ArrayList<>(properties.getExcludeBranches()));
1049    excludeFilters = Collections.unmodifiableList(
1050         new ArrayList<>(properties.getExcludeFilters()));
1051    includeAttributes = Collections.unmodifiableList(
1052         new ArrayList<>(properties.getIncludeAttributes()));
1053    includeBranches = Collections.unmodifiableList(
1054         new ArrayList<>(properties.getIncludeBranches()));
1055    includeFilters = Collections.unmodifiableList(
1056         new ArrayList<>(properties.getIncludeFilters()));
1057    postExportTaskProcessors = Collections.unmodifiableList(
1058         new ArrayList<>(properties.getPostExportTaskProcessors()));
1059    backendID = properties.getBackendID();
1060    encryptionPassphraseFile = properties.getEncryptionPassphraseFile();
1061    encryptionSettingsDefinitionID =
1062         properties.getEncryptionSettingsDefinitionID();
1063    ldifFile = properties.getLDIFFile();
1064  }
1065
1066
1067
1068  /**
1069   * Creates a new export task from the provided entry.
1070   *
1071   * @param  entry  The entry to use to create this export task.
1072   *
1073   * @throws  TaskException  If the provided entry cannot be parsed as an export
1074   *                         task entry.
1075   */
1076  public ExportTask(@NotNull final Entry entry)
1077         throws TaskException
1078  {
1079    super(entry);
1080
1081
1082    // Get the backend ID.  It must be present.
1083    backendID = entry.getAttributeValue(ATTR_BACKEND_ID);
1084    if (backendID == null)
1085    {
1086      throw new TaskException(ERR_EXPORT_TASK_NO_BACKEND_ID.get(
1087                                   getTaskEntryDN()));
1088    }
1089
1090
1091    // Get the LDIF file path.  It must be present.
1092    ldifFile = entry.getAttributeValue(ATTR_LDIF_FILE);
1093    if (ldifFile == null)
1094    {
1095      throw new TaskException(ERR_EXPORT_TASK_NO_LDIF_FILE.get(
1096                                   getTaskEntryDN()));
1097    }
1098
1099
1100    // Get the appendLDIF flag.  It may be absent.
1101    appendToLDIF = parseBooleanValue(entry, ATTR_APPEND_TO_LDIF, false);
1102
1103
1104    // Get the list of include branches.  It may be absent.
1105    includeBranches = parseStringList(entry, ATTR_INCLUDE_BRANCH);
1106
1107
1108    // Get the list of exclude branches.  It may be absent.
1109    excludeBranches = parseStringList(entry, ATTR_EXCLUDE_BRANCH);
1110
1111
1112    // Get the list of include filters.  It may be absent.
1113    includeFilters = parseStringList(entry, ATTR_INCLUDE_FILTER);
1114
1115
1116    // Get the list of exclude filters.  It may be absent.
1117    excludeFilters = parseStringList(entry, ATTR_EXCLUDE_FILTER);
1118
1119
1120    // Get the list of include attributes.  It may be absent.
1121    includeAttributes = parseStringList(entry, ATTR_INCLUDE_ATTRIBUTE);
1122
1123
1124    // Get the list of exclude attributes.  It may be absent.
1125    excludeAttributes = parseStringList(entry, ATTR_EXCLUDE_ATTRIBUTE);
1126
1127
1128    // Get the wrap column.  It may be absent.
1129    final String wrapStr = entry.getAttributeValue(ATTR_WRAP_COLUMN);
1130    if (wrapStr == null)
1131    {
1132      wrapColumn = -1;
1133    }
1134    else
1135    {
1136      try
1137      {
1138        wrapColumn = Integer.parseInt(wrapStr);
1139      }
1140      catch (final Exception e)
1141      {
1142        Debug.debugException(e);
1143        throw new TaskException(ERR_EXPORT_TASK_CANNOT_PARSE_WRAP_COLUMN.get(
1144                                     getTaskEntryDN(), wrapStr), e);
1145      }
1146    }
1147
1148
1149    // Get the compress flag.  It may be absent.
1150    compress = parseBooleanValue(entry, ATTR_COMPRESS, false);
1151
1152
1153    // Get the encrypt flag.  It may be absent.
1154    encrypt = parseBooleanValue(entry, ATTR_ENCRYPT, false);
1155
1156
1157    // Get the path to the encryption passphrase file.  It may be absent.
1158    encryptionPassphraseFile =
1159         entry.getAttributeValue(ATTR_ENCRYPTION_PASSPHRASE_FILE);
1160
1161
1162    // Get the encryption settings definition ID.  It may be absent.
1163    encryptionSettingsDefinitionID =
1164         entry.getAttributeValue(ATTR_ENCRYPTION_SETTINGS_DEFINITION_ID);
1165
1166
1167    // Get the sign flag.  It may be absent.
1168    sign = parseBooleanValue(entry, ATTR_SIGN, false);
1169
1170
1171    // Get the maximum write rate in megabytes per second.  It may be absent.
1172    maxMegabytesPerSecond =
1173         entry.getAttributeValueAsInteger(ATTR_MAX_MEGABYTES_PER_SECOND);
1174
1175
1176    // Get the names or DNs of the post-LDIF-export task processors that should
1177    // be invoked.
1178    postExportTaskProcessors =
1179         parseStringList(entry, ATTR_POST_EXPORT_PROCESSOR);
1180  }
1181
1182
1183
1184  /**
1185   * Creates a new export task from the provided set of task properties.
1186   *
1187   * @param  properties  The set of task properties and their corresponding
1188   *                     values to use for the task.  It must not be
1189   *                     {@code null}.
1190   *
1191   * @throws  TaskException  If the provided set of properties cannot be used to
1192   *                         create a valid export task.
1193   */
1194  public ExportTask(@NotNull final Map<TaskProperty,List<Object>> properties)
1195         throws TaskException
1196  {
1197    super(EXPORT_TASK_CLASS, properties);
1198
1199    boolean  a         = false;
1200    boolean  c         = false;
1201    boolean  e         = false;
1202    boolean  s         = false;
1203    Integer  maxMB     = null;
1204    long     w         = 0;
1205    String   b         = null;
1206    String   encID     = null;
1207    String   encPWFile = null;
1208    String   l         = null;
1209    String[] eA        = StaticUtils.NO_STRINGS;
1210    String[] eB        = StaticUtils.NO_STRINGS;
1211    String[] eF        = StaticUtils.NO_STRINGS;
1212    String[] iA        = StaticUtils.NO_STRINGS;
1213    String[] iB        = StaticUtils.NO_STRINGS;
1214    String[] iF        = StaticUtils.NO_STRINGS;
1215    String[] pEP       = StaticUtils.NO_STRINGS;
1216
1217    for (final Map.Entry<TaskProperty,List<Object>> entry :
1218         properties.entrySet())
1219    {
1220      final TaskProperty p = entry.getKey();
1221      final String attrName = p.getAttributeName();
1222      final List<Object> values = entry.getValue();
1223
1224      if (attrName.equalsIgnoreCase(ATTR_BACKEND_ID))
1225      {
1226        b = parseString(p, values, b);
1227      }
1228      else if (attrName.equalsIgnoreCase(ATTR_LDIF_FILE))
1229      {
1230        l = parseString(p, values, l);
1231      }
1232      else if (attrName.equalsIgnoreCase(ATTR_APPEND_TO_LDIF))
1233      {
1234        a = parseBoolean(p, values, a);
1235      }
1236      else if (attrName.equalsIgnoreCase(ATTR_INCLUDE_BRANCH))
1237      {
1238        iB = parseStrings(p, values, iB);
1239      }
1240      else if (attrName.equalsIgnoreCase(ATTR_EXCLUDE_BRANCH))
1241      {
1242        eB = parseStrings(p, values, eB);
1243      }
1244      else if (attrName.equalsIgnoreCase(ATTR_INCLUDE_FILTER))
1245      {
1246        iF = parseStrings(p, values, iF);
1247      }
1248      else if (attrName.equalsIgnoreCase(ATTR_EXCLUDE_FILTER))
1249      {
1250        eF = parseStrings(p, values, eF);
1251      }
1252      else if (attrName.equalsIgnoreCase(ATTR_INCLUDE_ATTRIBUTE))
1253      {
1254        iA = parseStrings(p, values, iA);
1255      }
1256      else if (attrName.equalsIgnoreCase(ATTR_EXCLUDE_ATTRIBUTE))
1257      {
1258        eA = parseStrings(p, values, eA);
1259      }
1260      else if (attrName.equalsIgnoreCase(ATTR_WRAP_COLUMN))
1261      {
1262        w = parseLong(p, values, w);
1263      }
1264      else if (attrName.equalsIgnoreCase(ATTR_COMPRESS))
1265      {
1266        c = parseBoolean(p, values, c);
1267      }
1268      else if (attrName.equalsIgnoreCase(ATTR_ENCRYPT))
1269      {
1270        e = parseBoolean(p, values, e);
1271      }
1272      else if (attrName.equalsIgnoreCase(ATTR_ENCRYPTION_PASSPHRASE_FILE))
1273      {
1274        encPWFile = parseString(p, values, encPWFile);
1275      }
1276      else if (attrName.equalsIgnoreCase(
1277           ATTR_ENCRYPTION_SETTINGS_DEFINITION_ID))
1278      {
1279        encID = parseString(p, values, encID);
1280      }
1281      else if (attrName.equalsIgnoreCase(ATTR_SIGN))
1282      {
1283        s = parseBoolean(p, values, s);
1284      }
1285      else if (attrName.equalsIgnoreCase(ATTR_MAX_MEGABYTES_PER_SECOND))
1286      {
1287        final Long maxMBLong = parseLong(p, values, null);
1288        if (maxMBLong == null)
1289        {
1290          maxMB = null;
1291        }
1292        else
1293        {
1294          maxMB = maxMBLong.intValue();
1295        }
1296      }
1297      else if (attrName.equalsIgnoreCase(ATTR_POST_EXPORT_PROCESSOR))
1298      {
1299        pEP = parseStrings(p, values, pEP);
1300      }
1301    }
1302
1303    if (b == null)
1304    {
1305      throw new TaskException(ERR_EXPORT_TASK_NO_BACKEND_ID.get(
1306                                   getTaskEntryDN()));
1307    }
1308
1309    if (l == null)
1310    {
1311      throw new TaskException(ERR_EXPORT_TASK_NO_LDIF_FILE.get(
1312                                   getTaskEntryDN()));
1313    }
1314
1315    backendID = b;
1316    ldifFile = l;
1317    appendToLDIF = a;
1318    includeAttributes = Collections.unmodifiableList(Arrays.asList(iA));
1319    excludeAttributes = Collections.unmodifiableList(Arrays.asList(eA));
1320    includeBranches = Collections.unmodifiableList(Arrays.asList(iB));
1321    excludeBranches = Collections.unmodifiableList(Arrays.asList(eB));
1322    includeFilters = Collections.unmodifiableList(Arrays.asList(iF));
1323    excludeFilters = Collections.unmodifiableList(Arrays.asList(eF));
1324    wrapColumn = (int) w;
1325    compress = c;
1326    encrypt = e;
1327    encryptionPassphraseFile = encPWFile;
1328    encryptionSettingsDefinitionID = encID;
1329    sign = s;
1330    maxMegabytesPerSecond = maxMB;
1331    postExportTaskProcessors = Collections.unmodifiableList(Arrays.asList(pEP));
1332  }
1333
1334
1335
1336  /**
1337   * {@inheritDoc}
1338   */
1339  @Override()
1340  @NotNull()
1341  public String getTaskName()
1342  {
1343    return INFO_TASK_NAME_EXPORT.get();
1344  }
1345
1346
1347
1348  /**
1349   * {@inheritDoc}
1350   */
1351  @Override()
1352  @NotNull()
1353  public String getTaskDescription()
1354  {
1355    return INFO_TASK_DESCRIPTION_EXPORT.get();
1356  }
1357
1358
1359
1360  /**
1361   * Retrieves the backend ID of the backend from which the data is to be
1362   * exported.
1363   *
1364   * @return  The backend ID of the backend from which the data is to be
1365   *          exported.
1366   */
1367  @NotNull()
1368  public String getBackendID()
1369  {
1370    return backendID;
1371  }
1372
1373
1374
1375  /**
1376   * Retrieves the path to the LDIF file to which the exported data should be
1377   * written.  It may be either an absolute path or one that is relative to the
1378   * server root.
1379   *
1380   * @return  The path to the LDIF file to which the exported data should be
1381   *          written.
1382   */
1383  @NotNull()
1384  public String getLDIFFile()
1385  {
1386    return ldifFile;
1387  }
1388
1389
1390
1391  /**
1392   * Indicates whether to append to the LDIF file rather than overwriting it if
1393   * it already exists.
1394   *
1395   * @return  {@code true} if the server should append to an existing LDIF file,
1396   *          or {@code false} if the server should overwrite it.
1397   */
1398  public boolean appendToLDIF()
1399  {
1400    return appendToLDIF;
1401  }
1402
1403
1404
1405  /**
1406   * Retrieves a list of base DNs of branches that should be included in the
1407   * export.
1408   *
1409   * @return  A list of base DNs of branches that should be included in the
1410   *          export, or an empty list if no entries should be excluded based on
1411   *          their location.
1412   */
1413  @NotNull()
1414  public List<String> getIncludeBranches()
1415  {
1416    return includeBranches;
1417  }
1418
1419
1420
1421  /**
1422   * Retrieves a list of base DNs of branches that should be excluded from the
1423   * export.
1424   *
1425   * @return  A list of base DNs of branches that should be excluded from the
1426   *          export, or an empty list if no entries should be excluded based on
1427   *          their location.
1428   */
1429  @NotNull()
1430  public List<String> getExcludeBranches()
1431  {
1432    return excludeBranches;
1433  }
1434
1435
1436
1437  /**
1438   * Retrieves a list of search filters that should be used to determine which
1439   * entries should be included in the export.
1440   *
1441   * @return  A list of search filters that should be used to determine which
1442   *          entries should be included in the export, or an empty list if no
1443   *          entries should be excluded based on their content.
1444   */
1445  @NotNull()
1446  public List<String> getIncludeFilters()
1447  {
1448    return includeFilters;
1449  }
1450
1451
1452
1453  /**
1454   * Retrieves a list of search filters that should be used to determine which
1455   * entries should be excluded from the export.
1456   *
1457   * @return  A list of search filters that should be used to determine which
1458   *          entries should be excluded from the export, or an empty list if no
1459   *          entries should be excluded based on their content.
1460   */
1461  @NotNull()
1462  public List<String> getExcludeFilters()
1463  {
1464    return excludeFilters;
1465  }
1466
1467
1468
1469  /**
1470   * Retrieves a list of the attributes that should be included in exported
1471   * entries.
1472   *
1473   * @return  A list of the attributes that should be included in exported
1474   *          entries, or an empty list if no attributes should be excluded.
1475   */
1476  @NotNull()
1477  public List<String> getIncludeAttributes()
1478  {
1479    return includeAttributes;
1480  }
1481
1482
1483
1484  /**
1485   * Retrieves a list of the attributes that should be excluded from exported
1486   * entries.
1487   *
1488   * @return  A list of the attributes that should be excluded from exported
1489   *          entries, or an empty list if no attributes should be excluded.
1490   */
1491  @NotNull()
1492  public List<String> getExcludeAttributes()
1493  {
1494    return excludeAttributes;
1495  }
1496
1497
1498
1499  /**
1500   * Retrieves the column number at which long lines should be wrapped.
1501   *
1502   * @return  The column number at which long lines should be wrapped, or a
1503   *          value less than or equal to zero to indicate that no wrapping
1504   *          should be performed.
1505   */
1506  public int getWrapColumn()
1507  {
1508    return wrapColumn;
1509  }
1510
1511
1512
1513  /**
1514   * Indicates whether the LDIF data should be compressed as it is exported.
1515   *
1516   * @return  {@code true} if the LDIF data should be compressed as it is
1517   *          exported, or {@code false} if not.
1518   */
1519  public boolean compress()
1520  {
1521    return compress;
1522  }
1523
1524
1525
1526  /**
1527   * Indicates whether the LDIF data should be encrypted as it is exported.
1528   *
1529   * @return  {@code true} if the LDIF data should be encrypted as it is
1530   *          exported, or {@code false} if not.
1531   */
1532  public boolean encrypt()
1533  {
1534    return encrypt;
1535  }
1536
1537
1538
1539  /**
1540   * Retrieves the path to a file that contains the passphrase to use to
1541   * generate the encryption key.
1542   *
1543   * @return  The path to a file that contains the passphrase to use to
1544   *          generate the encryption key, or {@code null} if the LDIF file
1545   *          should not be encrypted or if the encryption key should be
1546   *          obtained through some other means.
1547   */
1548  @Nullable()
1549  public String getEncryptionPassphraseFile()
1550  {
1551    return encryptionPassphraseFile;
1552  }
1553
1554
1555
1556  /**
1557   * Retrieves the identifier of the encryption settings definition to use to
1558   * generate the encryption key.
1559   *
1560   * @return  The identifier of the encryption settings definition to use to
1561   *          generate the encryption key, or {@code null} if the LDIF file
1562   *          should not be encrypted or if the encryption key should be
1563   *          obtained through some other means.
1564   */
1565  @Nullable()
1566  public String getEncryptionSettingsDefinitionID()
1567  {
1568    return encryptionSettingsDefinitionID;
1569  }
1570
1571
1572
1573  /**
1574   * Indicates whether the exported LDIF data should include a signed hash.
1575   *
1576   * @return  {@code true} if the exported LDIF data should include a signed
1577   *          hash, or {@code false} if not.
1578   */
1579  public boolean sign()
1580  {
1581    return sign;
1582  }
1583
1584
1585
1586  /**
1587   * Retrieves the maximum rate, in megabytes per second, at which the LDIF file
1588   * should be written.
1589   *
1590   * @return  The maximum rate, in megabytes per second, at which the LDIF file
1591   *          should be written, or {@code null} if the writing should not be
1592   *          rate limited.
1593   */
1594  @Nullable()
1595  public Integer getMaxMegabytesPerSecond()
1596  {
1597    return maxMegabytesPerSecond;
1598  }
1599
1600
1601
1602  /**
1603   * Retrieves a list containing the names or DNs of any post-LDIF-export task
1604   * processors that should be invoked for the export.
1605   *
1606   * @return  A list containing the names or DNs of any post-LDIF-export task
1607   *          processors that should be invoked for the export, or an empty list
1608   *          if no post-LDIF-export task processors should be invoked.
1609   */
1610  @NotNull()
1611  public List<String> getPostExportTaskProcessors()
1612  {
1613    return postExportTaskProcessors;
1614  }
1615
1616
1617
1618  /**
1619   * {@inheritDoc}
1620   */
1621  @Override()
1622  @NotNull()
1623  protected List<String> getAdditionalObjectClasses()
1624  {
1625    return Collections.singletonList(OC_EXPORT_TASK);
1626  }
1627
1628
1629
1630  /**
1631   * {@inheritDoc}
1632   */
1633  @Override()
1634  @NotNull()
1635  protected List<Attribute> getAdditionalAttributes()
1636  {
1637    final ArrayList<Attribute> attrs = new ArrayList<>(20);
1638
1639    attrs.add(new Attribute(ATTR_BACKEND_ID, backendID));
1640    attrs.add(new Attribute(ATTR_LDIF_FILE, ldifFile));
1641    attrs.add(new Attribute(ATTR_APPEND_TO_LDIF, String.valueOf(appendToLDIF)));
1642    attrs.add(new Attribute(ATTR_COMPRESS, String.valueOf(compress)));
1643    attrs.add(new Attribute(ATTR_ENCRYPT, String.valueOf(encrypt)));
1644    attrs.add(new Attribute(ATTR_SIGN, String.valueOf(sign)));
1645
1646    if (! includeBranches.isEmpty())
1647    {
1648      attrs.add(new Attribute(ATTR_INCLUDE_BRANCH, includeBranches));
1649    }
1650
1651    if (! excludeBranches.isEmpty())
1652    {
1653      attrs.add(new Attribute(ATTR_EXCLUDE_BRANCH, excludeBranches));
1654    }
1655
1656    if (! includeAttributes.isEmpty())
1657    {
1658      attrs.add(new Attribute(ATTR_INCLUDE_ATTRIBUTE, includeAttributes));
1659    }
1660
1661    if (! excludeAttributes.isEmpty())
1662    {
1663      attrs.add(new Attribute(ATTR_EXCLUDE_ATTRIBUTE, excludeAttributes));
1664    }
1665
1666    if (! includeFilters.isEmpty())
1667    {
1668      attrs.add(new Attribute(ATTR_INCLUDE_FILTER, includeFilters));
1669    }
1670
1671    if (! excludeFilters.isEmpty())
1672    {
1673      attrs.add(new Attribute(ATTR_EXCLUDE_FILTER, excludeFilters));
1674    }
1675
1676    if (wrapColumn > 0)
1677    {
1678      attrs.add(new Attribute(ATTR_WRAP_COLUMN, String.valueOf(wrapColumn)));
1679    }
1680
1681    if (encryptionPassphraseFile != null)
1682    {
1683      attrs.add(new Attribute(ATTR_ENCRYPTION_PASSPHRASE_FILE,
1684           encryptionPassphraseFile));
1685    }
1686
1687    if (encryptionSettingsDefinitionID != null)
1688    {
1689      attrs.add(new Attribute(ATTR_ENCRYPTION_SETTINGS_DEFINITION_ID,
1690           encryptionSettingsDefinitionID));
1691    }
1692
1693    if (maxMegabytesPerSecond != null)
1694    {
1695      attrs.add(new Attribute(ATTR_MAX_MEGABYTES_PER_SECOND,
1696           String.valueOf(maxMegabytesPerSecond)));
1697    }
1698
1699    if (! postExportTaskProcessors.isEmpty())
1700    {
1701      attrs.add(new Attribute(ATTR_POST_EXPORT_PROCESSOR,
1702           postExportTaskProcessors));
1703    }
1704
1705    return attrs;
1706  }
1707
1708
1709
1710  /**
1711   * {@inheritDoc}
1712   */
1713  @Override()
1714  @NotNull()
1715  public List<TaskProperty> getTaskSpecificProperties()
1716  {
1717    final List<TaskProperty> propList = Arrays.asList(
1718         PROPERTY_BACKEND_ID,
1719         PROPERTY_LDIF_FILE,
1720         PROPERTY_APPEND_TO_LDIF,
1721         PROPERTY_INCLUDE_BRANCH,
1722         PROPERTY_EXCLUDE_BRANCH,
1723         PROPERTY_INCLUDE_FILTER,
1724         PROPERTY_EXCLUDE_FILTER,
1725         PROPERTY_INCLUDE_ATTRIBUTE,
1726         PROPERTY_EXCLUDE_ATTRIBUTE,
1727         PROPERTY_WRAP_COLUMN,
1728         PROPERTY_COMPRESS,
1729         PROPERTY_ENCRYPT,
1730         PROPERTY_ENCRYPTION_PASSPHRASE_FILE,
1731         PROPERTY_ENCRYPTION_SETTINGS_DEFINITION_ID,
1732         PROPERTY_SIGN,
1733         PROPERTY_MAX_MEGABYTES_PER_SECOND,
1734         PROPERTY_POST_EXPORT_PROCESSOR);
1735
1736    return Collections.unmodifiableList(propList);
1737  }
1738
1739
1740
1741  /**
1742   * {@inheritDoc}
1743   */
1744  @Override()
1745  @NotNull()
1746  public Map<TaskProperty,List<Object>> getTaskPropertyValues()
1747  {
1748    final LinkedHashMap<TaskProperty,List<Object>> props =
1749         new LinkedHashMap<>(StaticUtils.computeMapCapacity(30));
1750
1751    props.put(PROPERTY_BACKEND_ID,
1752              Collections.<Object>singletonList(backendID));
1753
1754    props.put(PROPERTY_LDIF_FILE,
1755              Collections.<Object>singletonList(ldifFile));
1756
1757    props.put(PROPERTY_APPEND_TO_LDIF,
1758              Collections.<Object>singletonList(appendToLDIF));
1759
1760    props.put(PROPERTY_INCLUDE_BRANCH,
1761              Collections.<Object>unmodifiableList(includeBranches));
1762
1763    props.put(PROPERTY_EXCLUDE_BRANCH,
1764              Collections.<Object>unmodifiableList(excludeBranches));
1765
1766    props.put(PROPERTY_INCLUDE_FILTER,
1767              Collections.<Object>unmodifiableList(includeFilters));
1768
1769    props.put(PROPERTY_EXCLUDE_FILTER,
1770              Collections.<Object>unmodifiableList(excludeFilters));
1771
1772    props.put(PROPERTY_INCLUDE_ATTRIBUTE,
1773              Collections.<Object>unmodifiableList(includeAttributes));
1774
1775    props.put(PROPERTY_EXCLUDE_ATTRIBUTE,
1776              Collections.<Object>unmodifiableList(excludeAttributes));
1777
1778    props.put(PROPERTY_WRAP_COLUMN,
1779              Collections.<Object>singletonList((long) wrapColumn));
1780
1781    props.put(PROPERTY_COMPRESS,
1782              Collections.<Object>singletonList(compress));
1783
1784    props.put(PROPERTY_ENCRYPT,
1785              Collections.<Object>singletonList(encrypt));
1786
1787    if (encryptionPassphraseFile == null)
1788    {
1789      props.put(PROPERTY_ENCRYPTION_PASSPHRASE_FILE, Collections.emptyList());
1790    }
1791    else
1792    {
1793      props.put(PROPERTY_ENCRYPTION_PASSPHRASE_FILE,
1794         Collections.<Object>singletonList(encryptionPassphraseFile));
1795    }
1796
1797    if (encryptionSettingsDefinitionID == null)
1798    {
1799      props.put(PROPERTY_ENCRYPTION_SETTINGS_DEFINITION_ID,
1800           Collections.emptyList());
1801    }
1802    else
1803    {
1804      props.put(PROPERTY_ENCRYPTION_SETTINGS_DEFINITION_ID,
1805         Collections.<Object>singletonList(encryptionSettingsDefinitionID));
1806    }
1807
1808    props.put(PROPERTY_SIGN, Collections.<Object>singletonList(sign));
1809
1810    if (maxMegabytesPerSecond == null)
1811    {
1812      props.put(PROPERTY_MAX_MEGABYTES_PER_SECOND, Collections.emptyList());
1813    }
1814    else
1815    {
1816      props.put(PROPERTY_MAX_MEGABYTES_PER_SECOND,
1817         Collections.<Object>singletonList(maxMegabytesPerSecond.longValue()));
1818    }
1819
1820    props.put(PROPERTY_POST_EXPORT_PROCESSOR,
1821         Collections.<Object>unmodifiableList(postExportTaskProcessors));
1822
1823    props.putAll(super.getTaskPropertyValues());
1824    return Collections.unmodifiableMap(props);
1825  }
1826}