001/* 002 * Copyright 2008-2017 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2017 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 back up one or 047 * more Directory Server backends. 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 path to the directory in which the backup should be placed. If 062 * multiple backends are to be backed up at once, then this should be the 063 * parent of the backup directories for each backend. This must be 064 * provided when scheduling this task.</LI> 065 * <LI>The backend IDs of the backends to archive. If this is not provided, 066 * then the server will attempt to back up all supported backends.</LI> 067 * <LI>The backup ID to use for the backup. If this is not provided, then the 068 * server will generate a backup ID.</LI> 069 * <LI>A flag that indicates whether the backup should be an incremental 070 * backup (if the backend supports that capability) or a full backup.</LI> 071 * <LI>The backup ID of the existing backup on which the incremental backup 072 * should be based. If this is not provided and an incremental backup 073 * is to be performed, then it will be based on the most recent backup in 074 * the backup directory.</LI> 075 * <LI>A flag that indicates whether to compress the contents of the 076 * backup.</LI> 077 * <LI>A flag that indicates whether to encrypt the contents of the 078 * backup.</LI> 079 * <LI>A flag that indicates whether to hash the contents of the backup to use 080 * as a checksum for verifying the integrity of the backup.</LI> 081 * <LI>A flag that indicates whether to sign the backup hash in order to 082 * prevent anyone from tampering with it.</LI> 083 * </UL> 084 085 */ 086@NotMutable() 087@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 088public final class BackupTask 089 extends Task 090{ 091 /** 092 * The fully-qualified name of the Java class that is used for the backup 093 * task. 094 */ 095 static final String BACKUP_TASK_CLASS = 096 "com.unboundid.directory.server.tasks.BackupTask"; 097 098 099 100 /** 101 * The name of the attribute used to specify backend IDs of the backends to 102 * archive. 103 */ 104 private static final String ATTR_BACKEND_ID = "ds-task-backup-backend-id"; 105 106 107 108 /** 109 * The name of the attribute used to indicate whether to back up the contents 110 * of all supported backends. 111 */ 112 private static final String ATTR_BACKUP_ALL = "ds-task-backup-all"; 113 114 115 116 /** 117 * The name of the attribute used to specify the path to the directory in 118 * which the backup is to be written. 119 */ 120 private static final String ATTR_BACKUP_DIRECTORY = 121 "ds-backup-directory-path"; 122 123 124 125 /** 126 * The name of the attribute used to specify the backup ID for the backup. 127 */ 128 private static final String ATTR_BACKUP_ID = "ds-backup-id"; 129 130 131 132 /** 133 * The name of the attribute used to indicate whether to compress the backup. 134 */ 135 private static final String ATTR_COMPRESS = "ds-task-backup-compress"; 136 137 138 139 /** 140 * The name of the attribute used to indicate whether to encrypt the backup. 141 */ 142 private static final String ATTR_ENCRYPT = "ds-task-backup-encrypt"; 143 144 145 146 /** 147 * The name of the attribute used to indicate whether to create a hash of the 148 * backup. 149 */ 150 private static final String ATTR_HASH = "ds-task-backup-hash"; 151 152 153 154 /** 155 * The name of the attribute used to indicate whether to perform an 156 * incremental backup rather than a full backup. 157 */ 158 private static final String ATTR_INCREMENTAL = "ds-task-backup-incremental"; 159 160 161 162 /** 163 * The name of the attribute used to specify the backup ID of the backup 164 * on which to base the incremental backup. 165 */ 166 private static final String ATTR_INCREMENTAL_BASE_ID = 167 "ds-task-backup-incremental-base-id"; 168 169 170 171 /** 172 * The name of the attribute used to indicate whether to sign the hash of the 173 * backup. 174 */ 175 private static final String ATTR_SIGN_HASH = "ds-task-backup-sign-hash"; 176 177 178 179 /** 180 * The name of the object class used in backup task entries. 181 */ 182 private static final String OC_BACKUP_TASK = "ds-task-backup"; 183 184 185 186 /** 187 * The task property that will be used for the backup directory. 188 */ 189 private static final TaskProperty PROPERTY_BACKUP_DIRECTORY = 190 new TaskProperty(ATTR_BACKUP_DIRECTORY, 191 INFO_DISPLAY_NAME_BACKUP_DIRECTORY.get(), 192 INFO_DESCRIPTION_BACKUP_DIRECTORY_BACKUP.get(), 193 String.class, true, false, false); 194 195 196 197 /** 198 * The task property that will be used for the backend ID. 199 */ 200 private static final TaskProperty PROPERTY_BACKEND_ID = 201 new TaskProperty(ATTR_BACKEND_ID, INFO_DISPLAY_NAME_BACKEND_ID.get(), 202 INFO_DESCRIPTION_BACKEND_ID_BACKUP.get(), String.class, 203 false, true, false); 204 205 206 207 /** 208 * The task property that will be used for the backup ID. 209 */ 210 private static final TaskProperty PROPERTY_BACKUP_ID = 211 new TaskProperty(ATTR_BACKUP_ID, INFO_DISPLAY_NAME_BACKUP_ID.get(), 212 INFO_DESCRIPTION_BACKUP_ID_BACKUP.get(), String.class, 213 false, false, true); 214 215 216 217 /** 218 * The task property that will be used for the incremental flag. 219 */ 220 private static final TaskProperty PROPERTY_INCREMENTAL = 221 new TaskProperty(ATTR_INCREMENTAL, INFO_DISPLAY_NAME_INCREMENTAL.get(), 222 INFO_DESCRIPTION_INCREMENTAL.get(), Boolean.class, 223 false, false, false); 224 225 226 227 /** 228 * The task property that will be used for the incremental base ID. 229 */ 230 private static final TaskProperty PROPERTY_INCREMENTAL_BASE_ID = 231 new TaskProperty(ATTR_INCREMENTAL_BASE_ID, 232 INFO_DISPLAY_NAME_INCREMENTAL_BASE_ID.get(), 233 INFO_DESCRIPTION_INCREMENTAL_BASE_ID.get(), 234 String.class, false, false, true); 235 236 237 238 /** 239 * The task property that will be used for the compress flag. 240 */ 241 private static final TaskProperty PROPERTY_COMPRESS = 242 new TaskProperty(ATTR_COMPRESS, INFO_DISPLAY_NAME_COMPRESS.get(), 243 INFO_DESCRIPTION_COMPRESS_BACKUP.get(), Boolean.class, 244 false, false, false); 245 246 247 248 /** 249 * The task property that will be used for the encrypt flag. 250 */ 251 private static final TaskProperty PROPERTY_ENCRYPT = 252 new TaskProperty(ATTR_ENCRYPT, INFO_DISPLAY_NAME_ENCRYPT.get(), 253 INFO_DESCRIPTION_ENCRYPT_BACKUP.get(), Boolean.class, 254 false, false, false); 255 256 257 258 /** 259 * The task property that will be used for the hash flag. 260 */ 261 private static final TaskProperty PROPERTY_HASH = 262 new TaskProperty(ATTR_HASH, INFO_DISPLAY_NAME_HASH.get(), 263 INFO_DESCRIPTION_HASH_BACKUP.get(), Boolean.class, 264 false, false, false); 265 266 267 268 /** 269 * The task property that will be used for the sign hash flag. 270 */ 271 private static final TaskProperty PROPERTY_SIGN_HASH = 272 new TaskProperty(ATTR_SIGN_HASH, INFO_DISPLAY_NAME_SIGN_HASH.get(), 273 INFO_DESCRIPTION_SIGN_HASH_BACKUP.get(), Boolean.class, 274 false, false, false); 275 276 277 278 279 /** 280 * The serial version UID for this serializable class. 281 */ 282 private static final long serialVersionUID = 8680226715226034105L; 283 284 285 286 // Indicates whether to compress the backup. 287 private final boolean compress; 288 289 // Indicates whether to encrypt the backup. 290 private final boolean encrypt; 291 292 // Indicates whether to generate a hash of the backup. 293 private final boolean hash; 294 295 // Indicates whether to sign the backup hash. 296 private final boolean signHash; 297 298 // Indicates whether to perform an incremental backup. 299 private final boolean incremental; 300 301 // The backend IDs of the backends to back up. 302 private final List<String> backendIDs; 303 304 // The path to the directory in which to write the backup. 305 private final String backupDirectory; 306 307 // The backup ID to use for the backup. 308 private final String backupID; 309 310 // The backup ID of the backup to use as the base for the incremental backup. 311 private final String incrementalBaseID; 312 313 314 315 /** 316 * Creates a new uninitialized backup task instance which should only be 317 * used for obtaining general information about this task, including the task 318 * name, description, and supported properties. Attempts to use a task 319 * created with this constructor for any other reason will likely fail. 320 */ 321 public BackupTask() 322 { 323 compress = false; 324 encrypt = false; 325 hash = false; 326 signHash = false; 327 incremental = false; 328 backendIDs = null; 329 backupDirectory = null; 330 backupID = null; 331 incrementalBaseID = null; 332 } 333 334 335 336 337 /** 338 * Creates a new backup task with the provided information. 339 * 340 * @param taskID The task ID to use for this task. If it is 341 * {@code null} then a UUID will be generated for use 342 * as the task ID. 343 * @param backupDirectory The path to the directory on the server into which 344 * the backup should be written. If a single backend 345 * is to be archived, then this should be the path to 346 * the specific backup directory for that backend. 347 * If multiple backends are to be archived, then this 348 * should be the parent of the directories for each 349 * of the backends. It must not be {@code null}. 350 * @param backendID The backend ID of the backend to back up. It may 351 * be {@code null} if all supported backends should 352 * be backed up. 353 */ 354 public BackupTask(final String taskID, final String backupDirectory, 355 final String backendID) 356 { 357 this(taskID, backupDirectory, 358 ((backendID == null) ? null : Arrays.asList(backendID)), 359 null, false, null, false, false, false, false, null, null, null, null, 360 null); 361 } 362 363 364 365 /** 366 * Creates a new restore task with the provided information. 367 * 368 * @param taskID The task ID to use for this task. If it is 369 * {@code null} then a UUID will be generated 370 * for use as the task ID. 371 * @param backupDirectory The path to the directory on the server 372 * into which the backup should be written. 373 * If a single backend is to be archived, then 374 * this should be the path to the specific 375 * backup directory for that backend. If 376 * multiple backends are to be archived, then 377 * this should be the parent of the 378 * directories for each of the backends. It 379 * must not be {@code null}. 380 * @param backendIDs A list of the backend IDs of the backends 381 * to archive. It may be {@code null} or 382 * empty if all supported backends should be 383 * archived. 384 * @param backupID The backup ID to use for this backup. It 385 * may be {@code null} to indicate that the 386 * server should generate the backup ID. 387 * @param incremental Indicates whether to perform an incremental 388 * backup rather than a full backup. 389 * @param incrementalBaseID The backup ID of the existing backup on 390 * which to base the incremental backup. It 391 * may be {@code null} if this is not an 392 * incremental backup or if it should be based 393 * on the most recent backup. 394 * @param compress Indicates whether the backup should be 395 * compressed. 396 * @param encrypt Indicates whether the backup should be 397 * encrypted. 398 * @param hash Indicates whether to generate a hash of the 399 * backup contents. 400 * @param signHash Indicates whether to sign the hash of the 401 * backup contents. 402 * @param scheduledStartTime The time that this task should start 403 * running. 404 * @param dependencyIDs The list of task IDs that will be required 405 * to complete before this task will be 406 * eligible to start. 407 * @param failedDependencyAction Indicates what action should be taken if 408 * any of the dependencies for this task do 409 * not complete successfully. 410 * @param notifyOnCompletion The list of e-mail addresses of individuals 411 * that should be notified when this task 412 * completes. 413 * @param notifyOnError The list of e-mail addresses of individuals 414 * that should be notified if this task does 415 * not complete successfully. 416 */ 417 public BackupTask(final String taskID, final String backupDirectory, 418 final List<String> backendIDs, final String backupID, 419 final boolean incremental, final String incrementalBaseID, 420 final boolean compress, final boolean encrypt, 421 final boolean hash, final boolean signHash, 422 final Date scheduledStartTime, 423 final List<String> dependencyIDs, 424 final FailedDependencyAction failedDependencyAction, 425 final List<String> notifyOnCompletion, 426 final List<String> notifyOnError) 427 { 428 super(taskID, BACKUP_TASK_CLASS, scheduledStartTime, 429 dependencyIDs, failedDependencyAction, notifyOnCompletion, 430 notifyOnError); 431 432 ensureNotNull(backupDirectory); 433 434 this.backupDirectory = backupDirectory; 435 this.backupID = backupID; 436 this.incremental = incremental; 437 this.incrementalBaseID = incrementalBaseID; 438 this.compress = compress; 439 this.encrypt = encrypt; 440 this.hash = hash; 441 this.signHash = signHash; 442 443 if (backendIDs == null) 444 { 445 this.backendIDs = Collections.emptyList(); 446 } 447 else 448 { 449 this.backendIDs = Collections.unmodifiableList(backendIDs); 450 } 451 } 452 453 454 455 /** 456 * Creates a new backup task from the provided entry. 457 * 458 * @param entry The entry to use to create this backup task. 459 * 460 * @throws TaskException If the provided entry cannot be parsed as a backup 461 * task entry. 462 */ 463 public BackupTask(final Entry entry) 464 throws TaskException 465 { 466 super(entry); 467 468 469 // Get the backup directory. It must be present. 470 backupDirectory = entry.getAttributeValue(ATTR_BACKUP_DIRECTORY); 471 if (backupDirectory == null) 472 { 473 throw new TaskException(ERR_BACKUP_NO_BACKUP_DIRECTORY.get( 474 getTaskEntryDN())); 475 } 476 477 478 // Get the set of backend IDs. It may be absent. 479 backendIDs = parseStringList(entry, ATTR_BACKEND_ID); 480 481 482 // Get the backup ID. It may be absent. 483 backupID = entry.getAttributeValue(ATTR_BACKUP_ID); 484 485 486 // Get the incremental flag. It may be absent. 487 incremental = parseBooleanValue(entry, ATTR_INCREMENTAL, false); 488 489 490 // Get the incremental base ID. It may be absent. 491 incrementalBaseID = entry.getAttributeValue(ATTR_INCREMENTAL_BASE_ID); 492 493 494 // Determine whether to compress the backup. It may be absent. 495 compress = parseBooleanValue(entry, ATTR_COMPRESS, false); 496 497 498 // Determine whether to encrypt the backup. It may be absent. 499 encrypt = parseBooleanValue(entry, ATTR_ENCRYPT, false); 500 501 502 // Determine whether to hash the backup. It may be absent. 503 hash = parseBooleanValue(entry, ATTR_HASH, false); 504 505 506 // Determine whether to sign the hash. It may be absent. 507 signHash = parseBooleanValue(entry, ATTR_SIGN_HASH, false); 508 } 509 510 511 512 /** 513 * Creates a new backup task from the provided set of task properties. 514 * 515 * @param properties The set of task properties and their corresponding 516 * values to use for the task. It must not be 517 * {@code null}. 518 * 519 * @throws TaskException If the provided set of properties cannot be used to 520 * create a valid backup task. 521 */ 522 public BackupTask(final Map<TaskProperty,List<Object>> properties) 523 throws TaskException 524 { 525 super(BACKUP_TASK_CLASS, properties); 526 527 boolean c = false; 528 boolean e = false; 529 boolean h = false; 530 boolean i = false; 531 boolean s = false; 532 String bDir = null; 533 String bkID = null; 534 String incID = null; 535 String[] beIDs = StaticUtils.NO_STRINGS; 536 537 for (final Map.Entry<TaskProperty,List<Object>> entry : 538 properties.entrySet()) 539 { 540 final TaskProperty p = entry.getKey(); 541 final String attrName = p.getAttributeName(); 542 final List<Object> values = entry.getValue(); 543 544 if (attrName.equalsIgnoreCase(ATTR_BACKUP_DIRECTORY)) 545 { 546 bDir = parseString(p, values, bDir); 547 } 548 else if (attrName.equalsIgnoreCase(ATTR_BACKEND_ID)) 549 { 550 beIDs = parseStrings(p, values, beIDs); 551 } 552 else if (attrName.equalsIgnoreCase(ATTR_BACKUP_ID)) 553 { 554 bkID = parseString(p, values, bkID); 555 } 556 else if (attrName.equalsIgnoreCase(ATTR_INCREMENTAL)) 557 { 558 i = parseBoolean(p, values, i); 559 } 560 else if (attrName.equalsIgnoreCase(ATTR_INCREMENTAL_BASE_ID)) 561 { 562 incID = parseString(p, values, incID); 563 } 564 else if (attrName.equalsIgnoreCase(ATTR_COMPRESS)) 565 { 566 c = parseBoolean(p, values, c); 567 } 568 else if (attrName.equalsIgnoreCase(ATTR_ENCRYPT)) 569 { 570 e = parseBoolean(p, values, e); 571 } 572 else if (attrName.equalsIgnoreCase(ATTR_HASH)) 573 { 574 h = parseBoolean(p, values, h); 575 } 576 else if (attrName.equalsIgnoreCase(ATTR_SIGN_HASH)) 577 { 578 s = parseBoolean(p, values, s); 579 } 580 } 581 582 if (bDir == null) 583 { 584 throw new TaskException(ERR_BACKUP_NO_BACKUP_DIRECTORY.get( 585 getTaskEntryDN())); 586 } 587 588 backupDirectory = bDir; 589 backendIDs = Arrays.asList(beIDs); 590 backupID = bkID; 591 incremental = i; 592 incrementalBaseID = incID; 593 compress = c; 594 encrypt = e; 595 hash = h; 596 signHash = s; 597 } 598 599 600 601 /** 602 * {@inheritDoc} 603 */ 604 @Override() 605 public String getTaskName() 606 { 607 return INFO_TASK_NAME_BACKUP.get(); 608 } 609 610 611 612 /** 613 * {@inheritDoc} 614 */ 615 @Override() 616 public String getTaskDescription() 617 { 618 return INFO_TASK_DESCRIPTION_BACKUP.get(); 619 } 620 621 622 623 /** 624 * Retrieves the path to the backup directory in which the backup files should 625 * be written. If a single backend is to be archived, then this will be the 626 * directory in which the backup files are written. If multiple backends are 627 * to be archived, then this will be the parent of the directories containing 628 * the backups for each backend. 629 * 630 * @return The path to the backup directory in which the backup files should 631 * be written. 632 */ 633 public String getBackupDirectory() 634 { 635 return backupDirectory; 636 } 637 638 639 640 /** 641 * Indicates whether the server should back up all supported backends. 642 * 643 * @return {@code true} if the server should back up all supported backends, 644 * or {@code false} if it should back up a specified backend or set 645 * of backends. 646 */ 647 public boolean backupAll() 648 { 649 return backendIDs.isEmpty(); 650 } 651 652 653 654 /** 655 * Retrieves the set of backend IDs for the backends that should be archived. 656 * 657 * @return The set of backend IDs for the backends that should be archived, 658 * or an empty list if the server should back up all supported 659 * backends. 660 */ 661 public List<String> getBackendIDs() 662 { 663 return backendIDs; 664 } 665 666 667 668 /** 669 * Retrieves the backup ID for the backup to generate. 670 * 671 * @return The backup ID for the backup to generate, or {@code null} if the 672 * server should generate a backup ID. 673 */ 674 public String getBackupID() 675 { 676 return backupID; 677 } 678 679 680 681 /** 682 * Indicates whether the server should attempt to perform an incremental 683 * backup rather than a full backup. 684 * 685 * @return {@code true} if the server should attempt to perform an 686 * incremental backup, or {@code false} for a full backup. 687 */ 688 public boolean incremental() 689 { 690 return incremental; 691 } 692 693 694 695 /** 696 * Retrieves the backup ID of the existing backup on which the incremental 697 * backup should be based. 698 * 699 * @return The backup ID of the existing backup on which the incremental 700 * backup should be based, or {@code null} if it is not an 701 * incremental backup or the server should use the most recent 702 * backup available as the base for the new incremental backup. 703 */ 704 public String getIncrementalBaseID() 705 { 706 return incrementalBaseID; 707 } 708 709 710 711 /** 712 * Indicates whether the backup should be compressed. 713 * 714 * @return {@code true} if the backup should be compressed, or {@code false} 715 * if not. 716 */ 717 public boolean compress() 718 { 719 return compress; 720 } 721 722 723 724 /** 725 * Indicates whether the backup should be encrypted. 726 * 727 * @return {@code true} if the backup should be encrypted, or {@code false} 728 * if not. 729 */ 730 public boolean encrypt() 731 { 732 return encrypt; 733 } 734 735 736 737 /** 738 * Indicates whether the server should generate a hash of the backup. 739 * 740 * @return {@code true} if the server should generate a hash of the backup, 741 * or {@code false} if not. 742 */ 743 public boolean hash() 744 { 745 return hash; 746 } 747 748 749 750 /** 751 * Indicates whether the server should sign the backup hash. 752 * 753 * @return {@code true} if the server should sign the backup hash, or 754 * {@code false} if not. 755 */ 756 public boolean signHash() 757 { 758 return signHash; 759 } 760 761 762 763 /** 764 * {@inheritDoc} 765 */ 766 @Override() 767 protected List<String> getAdditionalObjectClasses() 768 { 769 return Arrays.asList(OC_BACKUP_TASK); 770 } 771 772 773 774 /** 775 * {@inheritDoc} 776 */ 777 @Override() 778 protected List<Attribute> getAdditionalAttributes() 779 { 780 final ArrayList<Attribute> attrs = new ArrayList<Attribute>(9); 781 782 attrs.add(new Attribute(ATTR_BACKUP_DIRECTORY, backupDirectory)); 783 attrs.add(new Attribute(ATTR_INCREMENTAL, String.valueOf(incremental))); 784 attrs.add(new Attribute(ATTR_COMPRESS, String.valueOf(compress))); 785 attrs.add(new Attribute(ATTR_ENCRYPT, String.valueOf(encrypt))); 786 attrs.add(new Attribute(ATTR_HASH, String.valueOf(hash))); 787 attrs.add(new Attribute(ATTR_SIGN_HASH, String.valueOf(signHash))); 788 789 if (backendIDs.isEmpty()) 790 { 791 attrs.add(new Attribute(ATTR_BACKUP_ALL, "true")); 792 } 793 else 794 { 795 attrs.add(new Attribute(ATTR_BACKEND_ID, backendIDs)); 796 } 797 798 if (backupID != null) 799 { 800 attrs.add(new Attribute(ATTR_BACKUP_ID, backupID)); 801 } 802 803 if (incrementalBaseID != null) 804 { 805 attrs.add(new Attribute(ATTR_INCREMENTAL_BASE_ID, incrementalBaseID)); 806 } 807 808 return attrs; 809 } 810 811 812 813 /** 814 * {@inheritDoc} 815 */ 816 @Override() 817 public List<TaskProperty> getTaskSpecificProperties() 818 { 819 final List<TaskProperty> propList = Arrays.asList( 820 PROPERTY_BACKUP_DIRECTORY, 821 PROPERTY_BACKEND_ID, 822 PROPERTY_BACKUP_ID, 823 PROPERTY_INCREMENTAL, 824 PROPERTY_INCREMENTAL_BASE_ID, 825 PROPERTY_COMPRESS, 826 PROPERTY_ENCRYPT, 827 PROPERTY_HASH, 828 PROPERTY_SIGN_HASH); 829 830 return Collections.unmodifiableList(propList); 831 } 832 833 834 835 /** 836 * {@inheritDoc} 837 */ 838 @Override() 839 public Map<TaskProperty,List<Object>> getTaskPropertyValues() 840 { 841 final LinkedHashMap<TaskProperty,List<Object>> props = 842 new LinkedHashMap<TaskProperty,List<Object>>(); 843 844 props.put(PROPERTY_BACKUP_DIRECTORY, 845 Collections.<Object>unmodifiableList(Arrays.asList(backupDirectory))); 846 847 props.put(PROPERTY_BACKEND_ID, 848 Collections.<Object>unmodifiableList(backendIDs)); 849 850 if (backupID == null) 851 { 852 props.put(PROPERTY_BACKUP_ID, Collections.emptyList()); 853 } 854 else 855 { 856 props.put(PROPERTY_BACKUP_ID, 857 Collections.<Object>unmodifiableList(Arrays.asList(backupID))); 858 } 859 860 props.put(PROPERTY_INCREMENTAL, 861 Collections.<Object>unmodifiableList(Arrays.asList(incremental))); 862 863 if (incrementalBaseID == null) 864 { 865 props.put(PROPERTY_INCREMENTAL_BASE_ID, Collections.emptyList()); 866 } 867 else 868 { 869 props.put(PROPERTY_INCREMENTAL_BASE_ID, 870 Collections.<Object>unmodifiableList(Arrays.asList( 871 incrementalBaseID))); 872 } 873 874 props.put(PROPERTY_COMPRESS, 875 Collections.<Object>unmodifiableList(Arrays.asList(compress))); 876 877 props.put(PROPERTY_ENCRYPT, 878 Collections.<Object>unmodifiableList(Arrays.asList(encrypt))); 879 880 props.put(PROPERTY_HASH, 881 Collections.<Object>unmodifiableList(Arrays.asList(hash))); 882 883 props.put(PROPERTY_SIGN_HASH, 884 Collections.<Object>unmodifiableList(Arrays.asList(signHash))); 885 886 props.putAll(super.getTaskPropertyValues()); 887 return Collections.unmodifiableMap(props); 888 } 889}