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