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