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