001 /*
002 * Copyright 2008-2015 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2015 UnboundID Corp.
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 */
021 package com.unboundid.ldap.sdk.unboundidds.tasks;
022
023
024
025 import java.util.ArrayList;
026 import java.util.Arrays;
027 import java.util.Collections;
028 import java.util.Date;
029 import java.util.LinkedHashMap;
030 import java.util.List;
031 import java.util.Map;
032
033 import com.unboundid.ldap.sdk.Attribute;
034 import com.unboundid.ldap.sdk.Entry;
035 import com.unboundid.util.NotMutable;
036 import com.unboundid.util.StaticUtils;
037 import com.unboundid.util.ThreadSafety;
038 import com.unboundid.util.ThreadSafetyLevel;
039
040 import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*;
041 import static com.unboundid.util.Debug.*;
042 import static com.unboundid.util.Validator.*;
043
044
045
046 /**
047 * <BLOCKQUOTE>
048 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID
049 * LDAP SDK for Java. It is not available for use in applications that
050 * include only the Standard Edition of the LDAP SDK, and is not supported for
051 * use in conjunction with non-UnboundID products.
052 * </BLOCKQUOTE>
053 * This class defines a Directory Server task that can be used to export the
054 * contents of a backend to LDIF. The properties that are available for use
055 * with this type of task include:
056 * <UL>
057 * <LI>The backend ID for the backend from which the data is to be exported.
058 * It must be provided when scheduling a task of this type.</LI>
059 * <LI>The path (on the server system) and name of the LDIF file to be
060 * written. It must be provided when scheduling a task of this type.</LI>
061 * <LI>A flag that indicates whether to append to any existing file or to
062 * overwrite it.</LI>
063 * <LI>An optional list of base DNs for branches that should be included in
064 * the export.</LI>
065 * <LI>An optional list of base DNs for branches that should be excluded from
066 * the export.</LI>
067 * <LI>An optional list of filters that may be used to determine whether an
068 * entry should be included in the export.</LI>
069 * <LI>An optional list of filters that may be used to determine whether an
070 * entry should be excluded from the export.</LI>
071 * <LI>An optional list of attributes that should be included in entries that
072 * are exported.</LI>
073 * <LI>An optional list of attributes that should be excluded form entries
074 * that are exported.</LI>
075 * <LI>An integer value that specifies the column at which long lines should
076 * be wrapped. A value less than or equal to zero indicates that no
077 * wrapping should be performed.</LI>
078 * <LI>A flag that indicates whether to compress the LDIF data as it is
079 * written.</LI>
080 * <LI>A flag that indicates whether to encrypt the LDIF data as it is
081 * written.</LI>
082 * <LI>A flag that indicates whether to generate a signature for the LDIF data
083 * as it is written.</LI>
084 * </UL>
085 */
086 @NotMutable()
087 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
088 public final class ExportTask
089 extends Task
090 {
091 /**
092 * The fully-qualified name of the Java class that is used for the export
093 * task.
094 */
095 static final String EXPORT_TASK_CLASS =
096 "com.unboundid.directory.server.tasks.ExportTask";
097
098
099
100 /**
101 * The name of the attribute used to indicate whether to append to an existing
102 * file.
103 */
104 private static final String ATTR_APPEND_TO_LDIF =
105 "ds-task-export-append-to-ldif";
106
107
108
109 /**
110 * The name of the attribute used to specify the backend ID of the backend to
111 * export.
112 */
113 private static final String ATTR_BACKEND_ID = "ds-task-export-backend-id";
114
115
116
117 /**
118 * The name of the attribute used to indicate whether the exported LDIF should
119 * be compressed as it is written.
120 */
121 private static final String ATTR_COMPRESS = "ds-task-export-compress-ldif";
122
123
124
125 /**
126 * The name of the attribute used to indicate whether the exported LDIF should
127 * be encrypted as it is written.
128 */
129 private static final String ATTR_ENCRYPT = "ds-task-export-encrypt-ldif";
130
131
132
133 /**
134 * The name of the attribute used to specify the attributes to exclude from
135 * the export.
136 */
137 private static final String ATTR_EXCLUDE_ATTRIBUTE =
138 "ds-task-export-exclude-attribute";
139
140
141
142 /**
143 * The name of the attribute used to specify the base DNs to exclude from the
144 * export.
145 */
146 private static final String ATTR_EXCLUDE_BRANCH =
147 "ds-task-export-exclude-branch";
148
149
150
151 /**
152 * The name of the attribute used to specify the filters to use to identify
153 * entries to exclude from the export.
154 */
155 private static final String ATTR_EXCLUDE_FILTER =
156 "ds-task-export-exclude-filter";
157
158
159
160 /**
161 * The name of the attribute used to specify the attributes to include in the
162 * export.
163 */
164 private static final String ATTR_INCLUDE_ATTRIBUTE =
165 "ds-task-export-include-attribute";
166
167
168
169 /**
170 * The name of the attribute used to specify the base DNs to include in the
171 * export.
172 */
173 private static final String ATTR_INCLUDE_BRANCH =
174 "ds-task-export-include-branch";
175
176
177
178 /**
179 * The name of the attribute used to specify the filters to use to identify
180 * entries to include in the export.
181 */
182 private static final String ATTR_INCLUDE_FILTER =
183 "ds-task-export-include-filter";
184
185
186
187 /**
188 * The name of the attribute used to specify the path to the LDIF file to be
189 * written.
190 */
191 private static final String ATTR_LDIF_FILE = "ds-task-export-ldif-file";
192
193
194
195 /**
196 * The name of the attribute used to indicate whether the exported LDIF should
197 * include a signed hash of the contents.
198 */
199 private static final String ATTR_SIGN = "ds-task-export-sign-hash";
200
201
202
203 /**
204 * The name of the attribute used to specify the column at which to wrap long
205 * lines in the export.
206 */
207 private static final String ATTR_WRAP_COLUMN = "ds-task-export-wrap-column";
208
209
210
211 /**
212 * The name of the object class used in export task entries.
213 */
214 private static final String OC_EXPORT_TASK = "ds-task-export";
215
216
217
218 /**
219 * The task property for the backend ID.
220 */
221 private static final TaskProperty PROPERTY_BACKEND_ID =
222 new TaskProperty(ATTR_BACKEND_ID, INFO_DISPLAY_NAME_BACKEND_ID.get(),
223 INFO_DESCRIPTION_BACKEND_ID_EXPORT.get(), String.class,
224 true, false, false);
225
226
227
228 /**
229 * The task property for the LDIF file.
230 */
231 private static final TaskProperty PROPERTY_LDIF_FILE =
232 new TaskProperty(ATTR_LDIF_FILE, INFO_DISPLAY_NAME_LDIF_FILE.get(),
233 INFO_DESCRIPTION_LDIF_FILE_EXPORT.get(), String.class,
234 true, false, false);
235
236
237
238 /**
239 * The task property for the append to LDIF flag.
240 */
241 private static final TaskProperty PROPERTY_APPEND_TO_LDIF =
242 new TaskProperty(ATTR_APPEND_TO_LDIF,
243 INFO_DISPLAY_NAME_APPEND_TO_LDIF.get(),
244 INFO_DESCRIPTION_APPEND_TO_LDIF.get(), Boolean.class,
245 false, false, true);
246
247
248
249 /**
250 * The task property for the include branches.
251 */
252 private static final TaskProperty PROPERTY_INCLUDE_BRANCH =
253 new TaskProperty(ATTR_INCLUDE_BRANCH,
254 INFO_DISPLAY_NAME_INCLUDE_BRANCH.get(),
255 INFO_DESCRIPTION_INCLUDE_BRANCH_EXPORT.get(),
256 String.class, false, true, true);
257
258
259
260 /**
261 * The task property for the exclude branches.
262 */
263 private static final TaskProperty PROPERTY_EXCLUDE_BRANCH =
264 new TaskProperty(ATTR_EXCLUDE_BRANCH,
265 INFO_DISPLAY_NAME_EXCLUDE_BRANCH.get(),
266 INFO_DESCRIPTION_EXCLUDE_BRANCH_EXPORT.get(),
267 String.class, false, true, true);
268
269
270
271 /**
272 * The task property for the include filters.
273 */
274 private static final TaskProperty PROPERTY_INCLUDE_FILTER =
275 new TaskProperty(ATTR_INCLUDE_FILTER,
276 INFO_DISPLAY_NAME_INCLUDE_FILTER.get(),
277 INFO_DESCRIPTION_INCLUDE_FILTER_EXPORT.get(),
278 String.class, false, true, true);
279
280
281
282 /**
283 * The task property for the exclude filters.
284 */
285 private static final TaskProperty PROPERTY_EXCLUDE_FILTER =
286 new TaskProperty(ATTR_EXCLUDE_FILTER,
287 INFO_DISPLAY_NAME_EXCLUDE_FILTER.get(),
288 INFO_DESCRIPTION_EXCLUDE_FILTER_EXPORT.get(),
289 String.class, false, true, true);
290
291
292
293 /**
294 * The task property for the include attributes.
295 */
296 private static final TaskProperty PROPERTY_INCLUDE_ATTRIBUTE =
297 new TaskProperty(ATTR_INCLUDE_ATTRIBUTE,
298 INFO_DISPLAY_NAME_INCLUDE_ATTRIBUTE.get(),
299 INFO_DESCRIPTION_INCLUDE_ATTRIBUTE_EXPORT.get(),
300 String.class, false, true, true);
301
302
303
304 /**
305 * The task property for the exclude attributes.
306 */
307 private static final TaskProperty PROPERTY_EXCLUDE_ATTRIBUTE =
308 new TaskProperty(ATTR_EXCLUDE_ATTRIBUTE,
309 INFO_DISPLAY_NAME_EXCLUDE_ATTRIBUTE.get(),
310 INFO_DESCRIPTION_EXCLUDE_ATTRIBUTE_EXPORT.get(),
311 String.class, false, true, true);
312
313
314
315 /**
316 * The task property for the wrap column.
317 */
318 private static final TaskProperty PROPERTY_WRAP_COLUMN =
319 new TaskProperty(ATTR_WRAP_COLUMN, INFO_DISPLAY_NAME_WRAP_COLUMN.get(),
320 INFO_DESCRIPTION_WRAP_COLUMN.get(), Long.class, false,
321 false, true);
322
323
324
325 /**
326 * The task property for the compress flag.
327 */
328 private static final TaskProperty PROPERTY_COMPRESS =
329 new TaskProperty(ATTR_COMPRESS, INFO_DISPLAY_NAME_COMPRESS.get(),
330 INFO_DESCRIPTION_COMPRESS_EXPORT.get(), Boolean.class,
331 false, false, false);
332
333
334
335 /**
336 * The task property for the encrypt flag.
337 */
338 private static final TaskProperty PROPERTY_ENCRYPT =
339 new TaskProperty(ATTR_ENCRYPT, INFO_DISPLAY_NAME_ENCRYPT.get(),
340 INFO_DESCRIPTION_ENCRYPT_EXPORT.get(), Boolean.class,
341 false, false, false);
342
343
344
345 /**
346 * The task property for the sign flag.
347 */
348 private static final TaskProperty PROPERTY_SIGN =
349 new TaskProperty(ATTR_SIGN, INFO_DISPLAY_NAME_SIGN.get(),
350 INFO_DESCRIPTION_SIGN_EXPORT.get(), Boolean.class,
351 false, false, false);
352
353
354
355 /**
356 * The serial version UID for this serializable class.
357 */
358 private static final long serialVersionUID = 5489855404880345160L;
359
360
361
362 // Indicates whether to append the data to an existing file.
363 private final boolean appendToLDIF;
364
365 // Indicates whether to compress the data.
366 private final boolean compress;
367
368 // Indicates whether to encrypt the data.
369 private final boolean encrypt;
370
371 // Indicates whether to sign the data.
372 private final boolean sign;
373
374 // The column at which to wrap long lines.
375 private final int wrapColumn;
376
377 // The set of attributes to exclude from the export.
378 private final List<String> excludeAttributes;
379
380 // The set of base DNs to exclude from the export.
381 private final List<String> excludeBranches;
382
383 // The set of filters to use to identify entries to exclude.
384 private final List<String> excludeFilters;
385
386 // The set of attributes to include in the export.
387 private final List<String> includeAttributes;
388
389 // The set of base DNs to include in the export.
390 private final List<String> includeBranches;
391
392 // The set of filters to use to identify entries to include.
393 private final List<String> includeFilters;
394
395 // The backend ID of the backend to export.
396 private final String backendID;
397
398 // The path to the LDIF file to generate.
399 private final String ldifFile;
400
401
402
403 /**
404 * Creates a new uninitialized export task instance which should only be used
405 * for obtaining general information about this task, including the task name,
406 * description, and supported properties. Attempts to use a task created with
407 * this constructor for any other reason will likely fail.
408 */
409 public ExportTask()
410 {
411 appendToLDIF = false;
412 compress = false;
413 encrypt = false;
414 sign = false;
415 wrapColumn = -1;
416 excludeAttributes = null;
417 excludeBranches = null;
418 excludeFilters = null;
419 includeAttributes = null;
420 includeBranches = null;
421 includeFilters = null;
422 backendID = null;
423 ldifFile = null;
424 }
425
426
427
428
429 /**
430 * Creates a new export task with the provided information.
431 *
432 * @param taskID The task ID to use for this task. If it is {@code null}
433 * then a UUID will be generated for use as the task ID.
434 * @param backendID The backend ID of the backend containing the data to
435 * export. It must not be {@code null}.
436 * @param ldifFile The path to the LDIF file to create. It may be an
437 * absolute path or a path relative to the server install
438 * root. It must not be {@code null}.
439 */
440 public ExportTask(final String taskID, final String backendID,
441 final String ldifFile)
442 {
443 this(taskID, backendID, ldifFile, false, null, null, null, null, null, null,
444 -1, false, false, false, null, null, null, null, null);
445 }
446
447
448
449 /**
450 * Creates a new export task with the provided information.
451 *
452 * @param taskID The task ID to use for this task. If it is
453 * {@code null} then a UUID will be generated
454 * for use as the task ID.
455 * @param backendID The backend ID of the backend to be
456 * exported. It must not be {@code null}.
457 * @param ldifFile The path to the LDIF file to be written.
458 * It may be an absolute path or one that is
459 * relative to the server root. It must not
460 * be {@code null}.
461 * @param appendToLDIF Indicates whether to an append to any
462 * existing file rather than overwriting it.
463 * @param includeBranches The set of base DNs of entries to include
464 * in the export. It may be {@code null} or
465 * empty if no entries should be excluded
466 * based on their location.
467 * @param excludeBranches The set of base DNs of entries to exclude
468 * from the export. It may be {@code null} or
469 * empty if no entries should be excluded
470 * based on their location.
471 * @param includeFilters The set of filters to use to match entries
472 * that should be included in the export. It
473 * may be {@code null} or empty if no entries
474 * should be excluded based on their content.
475 * @param excludeFilters The set of filters to use to match entries
476 * that should be excluded from the export.
477 * It may be {@code null} or empty if no
478 * entries should be excluded based on their
479 * content.
480 * @param includeAttributes The set of attributes that should be
481 * included in exported entries. It may be
482 * {@code null} or empty if all attributes
483 * should be included.
484 * @param excludeAttributes The set of attributes that should be
485 * excluded from exported entries. It may be
486 * {@code null} or empty if no attributes
487 * should be excluded.
488 * @param wrapColumn The column at which long lines should be
489 * wrapped. It may be less than or equal to
490 * zero to indicate that long lines should not
491 * be wrapped.
492 * @param compress Indicates whether the LDIF data should be
493 * compressed as it is written.
494 * @param encrypt Indicates whether the LDIF data should be
495 * encrypted as it is written.
496 * @param sign Indicates whether to include a signed hash
497 * of the content in the exported data.
498 * @param scheduledStartTime The time that this task should start
499 * running.
500 * @param dependencyIDs The list of task IDs that will be required
501 * to complete before this task will be
502 * eligible to start.
503 * @param failedDependencyAction Indicates what action should be taken if
504 * any of the dependencies for this task do
505 * not complete successfully.
506 * @param notifyOnCompletion The list of e-mail addresses of individuals
507 * that should be notified when this task
508 * completes.
509 * @param notifyOnError The list of e-mail addresses of individuals
510 * that should be notified if this task does
511 * not complete successfully.
512 */
513 public ExportTask(final String taskID, final String backendID,
514 final String ldifFile, final boolean appendToLDIF,
515 final List<String> includeBranches,
516 final List<String> excludeBranches,
517 final List<String> includeFilters,
518 final List<String> excludeFilters,
519 final List<String> includeAttributes,
520 final List<String> excludeAttributes, final int wrapColumn,
521 final boolean compress, final boolean encrypt,
522 final boolean sign, final Date scheduledStartTime,
523 final List<String> dependencyIDs,
524 final FailedDependencyAction failedDependencyAction,
525 final List<String> notifyOnCompletion,
526 final List<String> notifyOnError)
527 {
528 super(taskID, EXPORT_TASK_CLASS, scheduledStartTime,
529 dependencyIDs, failedDependencyAction, notifyOnCompletion,
530 notifyOnError);
531
532 ensureNotNull(backendID, ldifFile);
533
534 this.backendID = backendID;
535 this.ldifFile = ldifFile;
536 this.appendToLDIF = appendToLDIF;
537 this.wrapColumn = wrapColumn;
538 this.compress = compress;
539 this.encrypt = encrypt;
540 this.sign = sign;
541
542 if (includeBranches == null)
543 {
544 this.includeBranches = Collections.emptyList();
545 }
546 else
547 {
548 this.includeBranches = Collections.unmodifiableList(includeBranches);
549 }
550
551 if (excludeBranches == null)
552 {
553 this.excludeBranches = Collections.emptyList();
554 }
555 else
556 {
557 this.excludeBranches = Collections.unmodifiableList(excludeBranches);
558 }
559
560 if (includeFilters == null)
561 {
562 this.includeFilters = Collections.emptyList();
563 }
564 else
565 {
566 this.includeFilters = Collections.unmodifiableList(includeFilters);
567 }
568
569 if (excludeFilters == null)
570 {
571 this.excludeFilters = Collections.emptyList();
572 }
573 else
574 {
575 this.excludeFilters = Collections.unmodifiableList(excludeFilters);
576 }
577
578 if (includeAttributes == null)
579 {
580 this.includeAttributes = Collections.emptyList();
581 }
582 else
583 {
584 this.includeAttributes = Collections.unmodifiableList(includeAttributes);
585 }
586
587 if (excludeAttributes == null)
588 {
589 this.excludeAttributes = Collections.emptyList();
590 }
591 else
592 {
593 this.excludeAttributes = Collections.unmodifiableList(excludeAttributes);
594 }
595 }
596
597
598
599 /**
600 * Creates a new export task from the provided entry.
601 *
602 * @param entry The entry to use to create this export task.
603 *
604 * @throws TaskException If the provided entry cannot be parsed as an export
605 * task entry.
606 */
607 public ExportTask(final Entry entry)
608 throws TaskException
609 {
610 super(entry);
611
612
613 // Get the backend ID. It must be present.
614 backendID = entry.getAttributeValue(ATTR_BACKEND_ID);
615 if (backendID == null)
616 {
617 throw new TaskException(ERR_EXPORT_TASK_NO_BACKEND_ID.get(
618 getTaskEntryDN()));
619 }
620
621
622 // Get the LDIF file path. It must be present.
623 ldifFile = entry.getAttributeValue(ATTR_LDIF_FILE);
624 if (ldifFile == null)
625 {
626 throw new TaskException(ERR_EXPORT_TASK_NO_LDIF_FILE.get(
627 getTaskEntryDN()));
628 }
629
630
631 // Get the appendLDIF flag. It may be absent.
632 appendToLDIF = parseBooleanValue(entry, ATTR_APPEND_TO_LDIF, false);
633
634
635 // Get the list of include branches. It may be absent.
636 includeBranches = parseStringList(entry, ATTR_INCLUDE_BRANCH);
637
638
639 // Get the list of exclude branches. It may be absent.
640 excludeBranches = parseStringList(entry, ATTR_EXCLUDE_BRANCH);
641
642
643 // Get the list of include filters. It may be absent.
644 includeFilters = parseStringList(entry, ATTR_INCLUDE_FILTER);
645
646
647 // Get the list of exclude filters. It may be absent.
648 excludeFilters = parseStringList(entry, ATTR_EXCLUDE_FILTER);
649
650
651 // Get the list of include attributes. It may be absent.
652 includeAttributes = parseStringList(entry, ATTR_INCLUDE_ATTRIBUTE);
653
654
655 // Get the list of exclude attributes. It may be absent.
656 excludeAttributes = parseStringList(entry, ATTR_EXCLUDE_ATTRIBUTE);
657
658
659 // Get the wrap column. It may be absent.
660 final String wrapStr = entry.getAttributeValue(ATTR_WRAP_COLUMN);
661 if (wrapStr == null)
662 {
663 wrapColumn = -1;
664 }
665 else
666 {
667 try
668 {
669 wrapColumn = Integer.parseInt(wrapStr);
670 }
671 catch (Exception e)
672 {
673 debugException(e);
674 throw new TaskException(ERR_EXPORT_TASK_CANNOT_PARSE_WRAP_COLUMN.get(
675 getTaskEntryDN(), wrapStr), e);
676 }
677 }
678
679
680 // Get the compress flag. It may be absent.
681 compress = parseBooleanValue(entry, ATTR_COMPRESS, false);
682
683
684 // Get the encrypt flag. It may be absent.
685 encrypt = parseBooleanValue(entry, ATTR_ENCRYPT, false);
686
687
688 // Get the sign flag. It may be absent.
689 sign = parseBooleanValue(entry, ATTR_SIGN, false);
690 }
691
692
693
694 /**
695 * Creates a new export task from the provided set of task properties.
696 *
697 * @param properties The set of task properties and their corresponding
698 * values to use for the task. It must not be
699 * {@code null}.
700 *
701 * @throws TaskException If the provided set of properties cannot be used to
702 * create a valid export task.
703 */
704 public ExportTask(final Map<TaskProperty,List<Object>> properties)
705 throws TaskException
706 {
707 super(EXPORT_TASK_CLASS, properties);
708
709 boolean a = false;
710 boolean c = false;
711 boolean e = false;
712 boolean s = false;
713 long w = 0;
714 String b = null;
715 String l = null;
716 String[] eA = StaticUtils.NO_STRINGS;
717 String[] eB = StaticUtils.NO_STRINGS;
718 String[] eF = StaticUtils.NO_STRINGS;
719 String[] iA = StaticUtils.NO_STRINGS;
720 String[] iB = StaticUtils.NO_STRINGS;
721 String[] iF = StaticUtils.NO_STRINGS;
722
723 for (final Map.Entry<TaskProperty,List<Object>> entry :
724 properties.entrySet())
725 {
726 final TaskProperty p = entry.getKey();
727 final String attrName = p.getAttributeName();
728 final List<Object> values = entry.getValue();
729
730 if (attrName.equalsIgnoreCase(ATTR_BACKEND_ID))
731 {
732 b = parseString(p, values, b);
733 }
734 else if (attrName.equalsIgnoreCase(ATTR_LDIF_FILE))
735 {
736 l = parseString(p, values, l);
737 }
738 else if (attrName.equalsIgnoreCase(ATTR_APPEND_TO_LDIF))
739 {
740 a = parseBoolean(p, values, a);
741 }
742 else if (attrName.equalsIgnoreCase(ATTR_INCLUDE_BRANCH))
743 {
744 iB = parseStrings(p, values, iB);
745 }
746 else if (attrName.equalsIgnoreCase(ATTR_EXCLUDE_BRANCH))
747 {
748 eB = parseStrings(p, values, eB);
749 }
750 else if (attrName.equalsIgnoreCase(ATTR_INCLUDE_FILTER))
751 {
752 iF = parseStrings(p, values, iF);
753 }
754 else if (attrName.equalsIgnoreCase(ATTR_EXCLUDE_FILTER))
755 {
756 eF = parseStrings(p, values, eF);
757 }
758 else if (attrName.equalsIgnoreCase(ATTR_INCLUDE_ATTRIBUTE))
759 {
760 iA = parseStrings(p, values, iA);
761 }
762 else if (attrName.equalsIgnoreCase(ATTR_EXCLUDE_ATTRIBUTE))
763 {
764 eA = parseStrings(p, values, eA);
765 }
766 else if (attrName.equalsIgnoreCase(ATTR_WRAP_COLUMN))
767 {
768 w = parseLong(p, values, w);
769 }
770 else if (attrName.equalsIgnoreCase(ATTR_COMPRESS))
771 {
772 c = parseBoolean(p, values, c);
773 }
774 else if (attrName.equalsIgnoreCase(ATTR_ENCRYPT))
775 {
776 e = parseBoolean(p, values, e);
777 }
778 else if (attrName.equalsIgnoreCase(ATTR_SIGN))
779 {
780 s = parseBoolean(p, values, s);
781 }
782 }
783
784 if (b == null)
785 {
786 throw new TaskException(ERR_EXPORT_TASK_NO_BACKEND_ID.get(
787 getTaskEntryDN()));
788 }
789
790 if (l == null)
791 {
792 throw new TaskException(ERR_EXPORT_TASK_NO_LDIF_FILE.get(
793 getTaskEntryDN()));
794 }
795
796 backendID = b;
797 ldifFile = l;
798 appendToLDIF = a;
799 includeAttributes = Collections.unmodifiableList(Arrays.asList(iA));
800 excludeAttributes = Collections.unmodifiableList(Arrays.asList(eA));
801 includeBranches = Collections.unmodifiableList(Arrays.asList(iB));
802 excludeBranches = Collections.unmodifiableList(Arrays.asList(eB));
803 includeFilters = Collections.unmodifiableList(Arrays.asList(iF));
804 excludeFilters = Collections.unmodifiableList(Arrays.asList(eF));
805 wrapColumn = (int) w;
806 compress = c;
807 encrypt = e;
808 sign = s;
809 }
810
811
812
813 /**
814 * {@inheritDoc}
815 */
816 @Override()
817 public String getTaskName()
818 {
819 return INFO_TASK_NAME_EXPORT.get();
820 }
821
822
823
824 /**
825 * {@inheritDoc}
826 */
827 @Override()
828 public String getTaskDescription()
829 {
830 return INFO_TASK_DESCRIPTION_EXPORT.get();
831 }
832
833
834
835 /**
836 * Retrieves the backend ID of the backend from which the data is to be
837 * exported.
838 *
839 * @return The backend ID of the backend from which the data is to be
840 * exported.
841 */
842 public String getBackendID()
843 {
844 return backendID;
845 }
846
847
848
849 /**
850 * Retrieves the path to the LDIF file to which the exported data should be
851 * written. It may be either an absolute path or one that is relative to the
852 * server root.
853 *
854 * @return The path to the LDIF file to which the exported data should be
855 * written.
856 */
857 public String getLDIFFile()
858 {
859 return ldifFile;
860 }
861
862
863
864 /**
865 * Indicates whether to append to the LDIF file rather than overwriting it if
866 * it already exists.
867 *
868 * @return {@code true} if the server should append to an existing LDIF file,
869 * or {@code false} if the server should overwrite it.
870 */
871 public boolean appendToLDIF()
872 {
873 return appendToLDIF;
874 }
875
876
877
878 /**
879 * Retrieves a list of base DNs of branches that should be included in the
880 * export.
881 *
882 * @return A list of base DNs of branches that should be included in the
883 * export, or an empty list if no entries should be excluded based on
884 * their location.
885 */
886 public List<String> getIncludeBranches()
887 {
888 return includeBranches;
889 }
890
891
892
893 /**
894 * Retrieves a list of base DNs of branches that should be excluded from the
895 * export.
896 *
897 * @return A list of base DNs of branches that should be excluded from the
898 * export, or an empty list if no entries should be excluded based on
899 * their location.
900 */
901 public List<String> getExcludeBranches()
902 {
903 return excludeBranches;
904 }
905
906
907
908 /**
909 * Retrieves a list of search filters that should be used to determine which
910 * entries should be included in the export.
911 *
912 * @return A list of search filters that should be used to determine which
913 * entries should be included in the export, or an empty list if no
914 * entries should be excluded based on their content.
915 */
916 public List<String> getIncludeFilters()
917 {
918 return includeFilters;
919 }
920
921
922
923 /**
924 * Retrieves a list of search filters that should be used to determine which
925 * entries should be excluded from the export.
926 *
927 * @return A list of search filters that should be used to determine which
928 * entries should be excluded from the export, or an empty list if no
929 * entries should be excluded based on their content.
930 */
931 public List<String> getExcludeFilters()
932 {
933 return excludeFilters;
934 }
935
936
937
938 /**
939 * Retrieves a list of the attributes that should be included in exported
940 * entries.
941 *
942 * @return A list of the attributes that should be included in exported
943 * entries, or an empty list if no attributes should be excluded.
944 */
945 public List<String> getIncludeAttributes()
946 {
947 return includeAttributes;
948 }
949
950
951
952 /**
953 * Retrieves a list of the attributes that should be excluded from exported
954 * entries.
955 *
956 * @return A list of the attributes that should be excluded from exported
957 * entries, or an empty list if no attributes should be excluded.
958 */
959 public List<String> getExcludeAttributes()
960 {
961 return excludeAttributes;
962 }
963
964
965
966 /**
967 * Retrieves the column number at which long lines should be wrapped.
968 *
969 * @return The column number at which long lines should be wrapped, or a
970 * value less than or equal to zero to indicate that no wrapping
971 * should be performed.
972 */
973 public int getWrapColumn()
974 {
975 return wrapColumn;
976 }
977
978
979
980 /**
981 * Indicates whether the LDIF data should be compressed as it is exported.
982 *
983 * @return {@code true} if the LDIF data should be compressed as it is
984 * exported, or {@code false} if not.
985 */
986 public boolean compress()
987 {
988 return compress;
989 }
990
991
992
993 /**
994 * Indicates whether the LDIF data should be encrypted as it is exported.
995 *
996 * @return {@code true} if the LDIF data should be encrypted as it is
997 * exported, or {@code false} if not.
998 */
999 public boolean encrypt()
1000 {
1001 return encrypt;
1002 }
1003
1004
1005
1006 /**
1007 * Indicates whether the exported LDIF data should include a signed hash.
1008 *
1009 * @return {@code true} if the exported LDIF data should include a signed
1010 * hash, or {@code false} if not.
1011 */
1012 public boolean sign()
1013 {
1014 return sign;
1015 }
1016
1017
1018
1019 /**
1020 * {@inheritDoc}
1021 */
1022 @Override()
1023 protected List<String> getAdditionalObjectClasses()
1024 {
1025 return Arrays.asList(OC_EXPORT_TASK);
1026 }
1027
1028
1029
1030 /**
1031 * {@inheritDoc}
1032 */
1033 @Override()
1034 protected List<Attribute> getAdditionalAttributes()
1035 {
1036 final ArrayList<Attribute> attrs = new ArrayList<Attribute>(13);
1037
1038 attrs.add(new Attribute(ATTR_BACKEND_ID, backendID));
1039 attrs.add(new Attribute(ATTR_LDIF_FILE, ldifFile));
1040 attrs.add(new Attribute(ATTR_APPEND_TO_LDIF, String.valueOf(appendToLDIF)));
1041 attrs.add(new Attribute(ATTR_COMPRESS, String.valueOf(compress)));
1042 attrs.add(new Attribute(ATTR_ENCRYPT, String.valueOf(encrypt)));
1043 attrs.add(new Attribute(ATTR_SIGN, String.valueOf(sign)));
1044
1045 if (! includeBranches.isEmpty())
1046 {
1047 attrs.add(new Attribute(ATTR_INCLUDE_BRANCH, includeBranches));
1048 }
1049
1050 if (! excludeBranches.isEmpty())
1051 {
1052 attrs.add(new Attribute(ATTR_EXCLUDE_BRANCH, excludeBranches));
1053 }
1054
1055 if (! includeAttributes.isEmpty())
1056 {
1057 attrs.add(new Attribute(ATTR_INCLUDE_ATTRIBUTE, includeAttributes));
1058 }
1059
1060 if (! excludeAttributes.isEmpty())
1061 {
1062 attrs.add(new Attribute(ATTR_EXCLUDE_ATTRIBUTE, excludeAttributes));
1063 }
1064
1065 if (! includeFilters.isEmpty())
1066 {
1067 attrs.add(new Attribute(ATTR_INCLUDE_FILTER, includeFilters));
1068 }
1069
1070 if (! excludeFilters.isEmpty())
1071 {
1072 attrs.add(new Attribute(ATTR_EXCLUDE_FILTER, excludeFilters));
1073 }
1074
1075 if (wrapColumn > 0)
1076 {
1077 attrs.add(new Attribute(ATTR_WRAP_COLUMN, String.valueOf(wrapColumn)));
1078 }
1079
1080 return attrs;
1081 }
1082
1083
1084
1085 /**
1086 * {@inheritDoc}
1087 */
1088 @Override()
1089 public List<TaskProperty> getTaskSpecificProperties()
1090 {
1091 final List<TaskProperty> propList = Arrays.asList(
1092 PROPERTY_BACKEND_ID,
1093 PROPERTY_LDIF_FILE,
1094 PROPERTY_APPEND_TO_LDIF,
1095 PROPERTY_INCLUDE_BRANCH,
1096 PROPERTY_EXCLUDE_BRANCH,
1097 PROPERTY_INCLUDE_FILTER,
1098 PROPERTY_EXCLUDE_FILTER,
1099 PROPERTY_INCLUDE_ATTRIBUTE,
1100 PROPERTY_EXCLUDE_ATTRIBUTE,
1101 PROPERTY_WRAP_COLUMN,
1102 PROPERTY_COMPRESS,
1103 PROPERTY_ENCRYPT,
1104 PROPERTY_SIGN);
1105
1106 return Collections.unmodifiableList(propList);
1107 }
1108
1109
1110
1111 /**
1112 * {@inheritDoc}
1113 */
1114 @Override()
1115 public Map<TaskProperty,List<Object>> getTaskPropertyValues()
1116 {
1117 final LinkedHashMap<TaskProperty,List<Object>> props =
1118 new LinkedHashMap<TaskProperty,List<Object>>();
1119
1120 props.put(PROPERTY_BACKEND_ID,
1121 Collections.<Object>unmodifiableList(Arrays.asList(backendID)));
1122
1123 props.put(PROPERTY_LDIF_FILE,
1124 Collections.<Object>unmodifiableList(Arrays.asList(ldifFile)));
1125
1126 props.put(PROPERTY_APPEND_TO_LDIF,
1127 Collections.<Object>unmodifiableList(Arrays.asList(
1128 appendToLDIF)));
1129
1130 props.put(PROPERTY_INCLUDE_BRANCH,
1131 Collections.<Object>unmodifiableList(includeBranches));
1132
1133 props.put(PROPERTY_EXCLUDE_BRANCH,
1134 Collections.<Object>unmodifiableList(excludeBranches));
1135
1136 props.put(PROPERTY_INCLUDE_FILTER,
1137 Collections.<Object>unmodifiableList(includeFilters));
1138
1139 props.put(PROPERTY_EXCLUDE_FILTER,
1140 Collections.<Object>unmodifiableList(excludeFilters));
1141
1142 props.put(PROPERTY_INCLUDE_ATTRIBUTE,
1143 Collections.<Object>unmodifiableList(includeAttributes));
1144
1145 props.put(PROPERTY_EXCLUDE_ATTRIBUTE,
1146 Collections.<Object>unmodifiableList(excludeAttributes));
1147
1148 props.put(PROPERTY_WRAP_COLUMN,
1149 Collections.<Object>unmodifiableList(Arrays.asList(
1150 Long.valueOf(wrapColumn))));
1151
1152 props.put(PROPERTY_COMPRESS,
1153 Collections.<Object>unmodifiableList(Arrays.asList(compress)));
1154
1155 props.put(PROPERTY_ENCRYPT,
1156 Collections.<Object>unmodifiableList(Arrays.asList(encrypt)));
1157
1158 props.put(PROPERTY_SIGN,
1159 Collections.<Object>unmodifiableList(Arrays.asList(sign)));
1160
1161 props.putAll(super.getTaskPropertyValues());
1162 return Collections.unmodifiableMap(props);
1163 }
1164 }