001/* 002 * Copyright 2011-2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2011-2020 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) 2015-2020 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.LinkedList; 046import java.util.List; 047import java.util.Map; 048 049import com.unboundid.ldap.sdk.Attribute; 050import com.unboundid.ldap.sdk.Entry; 051import com.unboundid.ldap.sdk.Filter; 052import com.unboundid.ldap.sdk.LDAPException; 053import com.unboundid.util.NotMutable; 054import com.unboundid.util.StaticUtils; 055import com.unboundid.util.ThreadSafety; 056import com.unboundid.util.ThreadSafetyLevel; 057import com.unboundid.util.Validator; 058 059import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*; 060 061 062 063/** 064 * This class defines a Directory Server task that can be used to cause the 065 * server to initiate a data security audit, which can look for potential 066 * issues in the environment that can impact the security of the directory 067 * environment. 068 * <BR> 069 * <BLOCKQUOTE> 070 * <B>NOTE:</B> This class, and other classes within the 071 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 072 * supported for use against Ping Identity, UnboundID, and 073 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 074 * for proprietary functionality or for external specifications that are not 075 * considered stable or mature enough to be guaranteed to work in an 076 * interoperable way with other types of LDAP servers. 077 * </BLOCKQUOTE> 078 * <BR> 079 * The properties that are available for use with this type of task include: 080 * <UL> 081 * <LI>The names of the auditors to include or exclude from the audit. This 082 * is optional, and if it is not provided, then all enabled auditors will 083 * be used.</LI> 084 * <LI>The backend IDs for the backends containing the data to be audited. 085 * This is optional, and if it is not provided then the server will run 086 * the audit in all backends that support this capability.</LI> 087 * <LI>A set of filters which identify the entries that should be examined by 088 * the audit. This is optional, and if it is not provided, then all 089 * entries in the selected backends will be included.</LI> 090 * <LI>The path to the directory in which the output files should be 091 * generated. This is optional, and if it is not provided then the server 092 * will use a default output directory.</LI> 093 * </UL> 094 */ 095@NotMutable() 096@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 097public final class AuditDataSecurityTask 098 extends Task 099{ 100 /** 101 * The fully-qualified name of the Java class that is used for the audit data 102 * security task. 103 */ 104 static final String AUDIT_DATA_SECURITY_TASK_CLASS = 105 "com.unboundid.directory.server.tasks.AuditDataSecurityTask"; 106 107 108 109 /** 110 * The name of the attribute used to specify the set of auditors to use to 111 * examine the data. 112 */ 113 private static final String ATTR_INCLUDE_AUDITOR = 114 "ds-task-audit-data-security-include-auditor"; 115 116 117 118 /** 119 * The name of the attribute used to specify the set of auditors that should 120 * not be used when examining the data. 121 */ 122 private static final String ATTR_EXCLUDE_AUDITOR = 123 "ds-task-audit-data-security-exclude-auditor"; 124 125 126 127 /** 128 * The name of the attribute used to the backend IDs for the backends in which 129 * the audit should be performed. 130 */ 131 private static final String ATTR_BACKEND_ID = 132 "ds-task-audit-data-security-backend-id"; 133 134 135 136 /** 137 * The name of the attribute used to specify a set of filters that should be 138 * used to identify entries to include in the audit. 139 */ 140 private static final String ATTR_REPORT_FILTER = 141 "ds-task-audit-data-security-report-filter"; 142 143 144 145 /** 146 * The name of the attribute used to specify the directory in which the report 147 * output files should be written. 148 */ 149 private static final String ATTR_OUTPUT_DIRECTORY = 150 "ds-task-audit-data-security-output-directory"; 151 152 153 154 /** 155 * The name of the object class used in audit data security task entries. 156 */ 157 private static final String OC_AUDIT_DATA_SECURITY_TASK = 158 "ds-task-audit-data-security"; 159 160 161 162 /** 163 * The task property that will be used for the included set of auditors. 164 */ 165 private static final TaskProperty PROPERTY_INCLUDE_AUDITOR = 166 new TaskProperty(ATTR_INCLUDE_AUDITOR, 167 INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_INCLUDE_AUDITOR.get(), 168 INFO_AUDIT_DATA_SECURITY_DESCRIPTION_INCLUDE_AUDITOR.get(), 169 String.class, false, true, false); 170 171 172 173 /** 174 * The task property that will be used for the excluded set of auditors. 175 */ 176 private static final TaskProperty PROPERTY_EXCLUDE_AUDITOR = 177 new TaskProperty(ATTR_EXCLUDE_AUDITOR, 178 INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_EXCLUDE_AUDITOR.get(), 179 INFO_AUDIT_DATA_SECURITY_DESCRIPTION_EXCLUDE_AUDITOR.get(), 180 String.class, false, true, false); 181 182 183 184 /** 185 * The task property that will be used for the backend IDs. 186 */ 187 private static final TaskProperty PROPERTY_BACKEND_ID = 188 new TaskProperty(ATTR_BACKEND_ID, 189 INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_BACKEND_ID.get(), 190 INFO_AUDIT_DATA_SECURITY_DESCRIPTION_BACKEND_ID.get(), 191 String.class, false, true, false); 192 193 194 195 /** 196 * The task property that will be used for the report filters. 197 */ 198 private static final TaskProperty PROPERTY_REPORT_FILTER = 199 new TaskProperty(ATTR_REPORT_FILTER, 200 INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_REPORT_FILTER.get(), 201 INFO_AUDIT_DATA_SECURITY_DESCRIPTION_REPORT_FILTER.get(), 202 String.class, false, true, false); 203 204 205 206 /** 207 * The task property that will be used for the output directory. 208 */ 209 private static final TaskProperty PROPERTY_OUTPUT_DIRECTORY = 210 new TaskProperty(ATTR_OUTPUT_DIRECTORY, 211 INFO_AUDIT_DATA_SECURITY_DISPLAY_NAME_OUTPUT_DIR.get(), 212 INFO_AUDIT_DATA_SECURITY_DESCRIPTION_OUTPUT_DIR.get(), 213 String.class, false, false, false); 214 215 216 217 /** 218 * The serial version UID for this serializable class. 219 */ 220 private static final long serialVersionUID = -4994621474763299632L; 221 222 223 224 // The backend IDs of the backends in which the audit should be performed. 225 private final List<String> backendIDs; 226 227 // The names of the excluded auditors to use in the audit. 228 private final List<String> excludeAuditors; 229 230 // The names of the included auditors to use in the audit. 231 private final List<String> includeAuditors; 232 233 // The report filters to select entries to audit. 234 private final List<String> reportFilters; 235 236 // The path of the output directory to use for report data files. 237 private final String outputDirectory; 238 239 240 241 /** 242 * Creates a new uninitialized audit data security task instance which should 243 * only be used for obtaining general information about this task, including 244 * the task name, description, and supported properties. Attempts to use a 245 * task created with this constructor for any other reason will likely fail. 246 */ 247 public AuditDataSecurityTask() 248 { 249 excludeAuditors = null; 250 includeAuditors = null; 251 backendIDs = null; 252 reportFilters = null; 253 outputDirectory = null; 254 } 255 256 257 258 /** 259 * Creates a new audit data security task with the provided information and 260 * default settings for all general task properties. 261 * 262 * @param includeAuditors The names of the auditors that should be used to 263 * examine the data. It may be {@code null} or empty 264 * if an exclude list should be provided, or if all 265 * enabled auditors should be invoked. You must not 266 * provide both include and exclude auditors. 267 * @param excludeAuditors The names of the auditors that should be excluded 268 * when examining the data. It may be {@code null} 269 * or empty if an include list should be provided, or 270 * if all enabled auditors should be invoked. You 271 * must not provide both include and exclude 272 * auditors. 273 * @param backendIDs The backend IDs of the backends containing the 274 * data to examine. It may be {@code null} or empty 275 * if all supported backends should be selected. 276 * @param reportFilters A set of filters which identify entries that 277 * should be examined. It may be {@code null} or 278 * empty if all entries should be examined. 279 * @param outputDirectory The path to the output directory (on the server 280 * filesystem) in which report data files should be 281 * written. It may be {@code null} if a default 282 * output directory should be used. 283 */ 284 public AuditDataSecurityTask(final List<String> includeAuditors, 285 final List<String> excludeAuditors, 286 final List<String> backendIDs, 287 final List<String> reportFilters, 288 final String outputDirectory) 289 { 290 this(null, includeAuditors, excludeAuditors, backendIDs, reportFilters, 291 outputDirectory, null, null, null, null, null); 292 } 293 294 295 296 /** 297 * Creates a new audit data security task with the provided information. 298 * 299 * @param taskID The task ID to use for this task. If it is 300 * {@code null} then a UUID will be generated 301 * for use as the task ID. 302 * @param includeAuditors The names of the auditors that should be 303 * used to examine the data. It may be 304 * {@code null} or empty if an exclude list 305 * should be provided, or if all enabled 306 * auditors should be invoked. You must not 307 * provide both include and exclude auditors. 308 * @param excludeAuditors The names of the auditors that should be 309 * excluded when examining the data. It may 310 * be {@code null} or empty if an include list 311 * should be provided, or if all enabled 312 * auditors should be invoked. You must not 313 * provide both include and exclude auditors. 314 * @param backendIDs The backend IDs of the backends containing 315 * the data to examine. It may be 316 * {@code null} or empty if all supported 317 * backends should be selected. 318 * @param reportFilters A set of filters which identify entries 319 * that should be examined. It may be 320 * {@code null} or empty if all entries should 321 * be examined. 322 * @param outputDirectory The path to the output directory (on the 323 * server filesystem) in which report data 324 * files should be written. It may be 325 * {@code null} if a default output directory 326 * should be used. 327 * @param scheduledStartTime The time that this task should start 328 * running. 329 * @param dependencyIDs The list of task IDs that will be required 330 * to complete before this task will be 331 * eligible to start. 332 * @param failedDependencyAction Indicates what action should be taken if 333 * any of the dependencies for this task do 334 * not complete successfully. 335 * @param notifyOnCompletion The list of e-mail addresses of individuals 336 * that should be notified when this task 337 * completes. 338 * @param notifyOnError The list of e-mail addresses of individuals 339 * that should be notified if this task does 340 * not complete successfully. 341 */ 342 public AuditDataSecurityTask(final String taskID, 343 final List<String> includeAuditors, 344 final List<String> excludeAuditors, final List<String> backendIDs, 345 final List<String> reportFilters, final String outputDirectory, 346 final Date scheduledStartTime, final List<String> dependencyIDs, 347 final FailedDependencyAction failedDependencyAction, 348 final List<String> notifyOnCompletion, 349 final List<String> notifyOnError) 350 { 351 this(taskID, includeAuditors, excludeAuditors, backendIDs, reportFilters, 352 outputDirectory, scheduledStartTime, dependencyIDs, 353 failedDependencyAction, null, notifyOnCompletion, null, 354 notifyOnError, null, null, null); 355 } 356 357 358 359 /** 360 * Creates a new audit data security task with the provided information. 361 * 362 * @param taskID The task ID to use for this task. If it is 363 * {@code null} then a UUID will be generated 364 * for use as the task ID. 365 * @param includeAuditors The names of the auditors that should be 366 * used to examine the data. It may be 367 * {@code null} or empty if an exclude list 368 * should be provided, or if all enabled 369 * auditors should be invoked. You must not 370 * provide both include and exclude auditors. 371 * @param excludeAuditors The names of the auditors that should be 372 * excluded when examining the data. It may 373 * be {@code null} or empty if an include list 374 * should be provided, or if all enabled 375 * auditors should be invoked. You must not 376 * provide both include and exclude auditors. 377 * @param backendIDs The backend IDs of the backends containing 378 * the data to examine. It may be 379 * {@code null} or empty if all supported 380 * backends should be selected. 381 * @param reportFilters A set of filters which identify entries 382 * that should be examined. It may be 383 * {@code null} or empty if all entries should 384 * be examined. 385 * @param outputDirectory The path to the output directory (on the 386 * server filesystem) in which report data 387 * files should be written. It may be 388 * {@code null} if a default output directory 389 * should be used. 390 * @param scheduledStartTime The time that this task should start 391 * running. 392 * @param dependencyIDs The list of task IDs that will be required 393 * to complete before this task will be 394 * eligible to start. 395 * @param failedDependencyAction Indicates what action should be taken if 396 * any of the dependencies for this task do 397 * not complete successfully. 398 * @param notifyOnStart The list of e-mail addresses of individuals 399 * that should be notified when this task 400 * starts running. 401 * @param notifyOnCompletion The list of e-mail addresses of individuals 402 * that should be notified when this task 403 * completes. 404 * @param notifyOnSuccess The list of e-mail addresses of individuals 405 * that should be notified if this task 406 * completes successfully. 407 * @param notifyOnError The list of e-mail addresses of individuals 408 * that should be notified if this task does 409 * not complete successfully. 410 * @param alertOnStart Indicates whether the server should send an 411 * alert notification when this task starts. 412 * @param alertOnSuccess Indicates whether the server should send an 413 * alert notification if this task completes 414 * successfully. 415 * @param alertOnError Indicates whether the server should send an 416 * alert notification if this task fails to 417 * complete successfully. 418 */ 419 public AuditDataSecurityTask(final String taskID, 420 final List<String> includeAuditors, 421 final List<String> excludeAuditors, final List<String> backendIDs, 422 final List<String> reportFilters, final String outputDirectory, 423 final Date scheduledStartTime, final List<String> dependencyIDs, 424 final FailedDependencyAction failedDependencyAction, 425 final List<String> notifyOnStart, 426 final List<String> notifyOnCompletion, 427 final List<String> notifyOnSuccess, 428 final List<String> notifyOnError, final Boolean alertOnStart, 429 final Boolean alertOnSuccess, final Boolean alertOnError) 430 { 431 super(taskID, AUDIT_DATA_SECURITY_TASK_CLASS, scheduledStartTime, 432 dependencyIDs, failedDependencyAction, notifyOnStart, 433 notifyOnCompletion, notifyOnSuccess, notifyOnError, alertOnStart, 434 alertOnSuccess, alertOnError); 435 436 this.includeAuditors = getStringList(includeAuditors); 437 this.excludeAuditors = getStringList(excludeAuditors); 438 this.backendIDs = getStringList(backendIDs); 439 this.reportFilters = getStringList(reportFilters); 440 this.outputDirectory = outputDirectory; 441 442 Validator.ensureTrue( 443 (this.includeAuditors.isEmpty() || this.excludeAuditors.isEmpty()), 444 "You cannot request both include and exclude auditors."); 445 } 446 447 448 449 /** 450 * Creates a new audit data security task from the provided entry. 451 * 452 * @param entry The entry to use to create this audit data security task. 453 * 454 * @throws TaskException If the provided entry cannot be parsed as an audit 455 * data security task entry. 456 */ 457 public AuditDataSecurityTask(final Entry entry) 458 throws TaskException 459 { 460 super(entry); 461 462 includeAuditors = Collections.unmodifiableList(StaticUtils.toNonNullList( 463 entry.getAttributeValues(ATTR_INCLUDE_AUDITOR))); 464 excludeAuditors = Collections.unmodifiableList(StaticUtils.toNonNullList( 465 entry.getAttributeValues(ATTR_EXCLUDE_AUDITOR))); 466 backendIDs = Collections.unmodifiableList(StaticUtils.toNonNullList( 467 entry.getAttributeValues(ATTR_BACKEND_ID))); 468 reportFilters = Collections.unmodifiableList(StaticUtils.toNonNullList( 469 entry.getAttributeValues(ATTR_REPORT_FILTER))); 470 outputDirectory = entry.getAttributeValue(ATTR_OUTPUT_DIRECTORY); 471 } 472 473 474 475 /** 476 * Creates a new audit data security task from the provided set of task 477 * properties. 478 * 479 * @param properties The set of task properties and their corresponding 480 * values to use for the task. It must not be 481 * {@code null}. 482 * 483 * @throws TaskException If the provided set of properties cannot be used to 484 * create a valid audit data security task. 485 */ 486 public AuditDataSecurityTask(final Map<TaskProperty,List<Object>> properties) 487 throws TaskException 488 { 489 super(AUDIT_DATA_SECURITY_TASK_CLASS, properties); 490 491 String outputDir = null; 492 final LinkedList<String> includeAuditorsList = new LinkedList<>(); 493 final LinkedList<String> excludeAuditorsList = new LinkedList<>(); 494 final LinkedList<String> backendIDList = new LinkedList<>(); 495 final LinkedList<String> reportFilterList = new LinkedList<>(); 496 for (final Map.Entry<TaskProperty,List<Object>> entry : 497 properties.entrySet()) 498 { 499 final TaskProperty p = entry.getKey(); 500 final String attrName = StaticUtils.toLowerCase(p.getAttributeName()); 501 final List<Object> values = entry.getValue(); 502 503 if (attrName.equals(ATTR_INCLUDE_AUDITOR)) 504 { 505 final String[] s = parseStrings(p, values, null); 506 if (s != null) 507 { 508 includeAuditorsList.addAll(Arrays.asList(s)); 509 } 510 } 511 else if (attrName.equals(ATTR_EXCLUDE_AUDITOR)) 512 { 513 final String[] s = parseStrings(p, values, null); 514 if (s != null) 515 { 516 excludeAuditorsList.addAll(Arrays.asList(s)); 517 } 518 } 519 else if (attrName.equals(ATTR_BACKEND_ID)) 520 { 521 final String[] s = parseStrings(p, values, null); 522 if (s != null) 523 { 524 backendIDList.addAll(Arrays.asList(s)); 525 } 526 } 527 else if (attrName.equals(ATTR_REPORT_FILTER)) 528 { 529 final String[] s = parseStrings(p, values, null); 530 if (s != null) 531 { 532 reportFilterList.addAll(Arrays.asList(s)); 533 } 534 } 535 else if (attrName.equals(ATTR_OUTPUT_DIRECTORY)) 536 { 537 outputDir = parseString(p, values, null); 538 } 539 } 540 541 includeAuditors = Collections.unmodifiableList(includeAuditorsList); 542 excludeAuditors = Collections.unmodifiableList(excludeAuditorsList); 543 backendIDs = Collections.unmodifiableList(backendIDList); 544 reportFilters = Collections.unmodifiableList(reportFilterList); 545 outputDirectory = outputDir; 546 547 if ((! includeAuditors.isEmpty()) && (! excludeAuditors.isEmpty())) 548 { 549 throw new TaskException( 550 ERR_AUDIT_DATA_SECURITY_BOTH_INCLUDE_AND_EXCLUDE_AUDITORS.get()); 551 } 552 } 553 554 555 556 /** 557 * {@inheritDoc} 558 */ 559 @Override() 560 public String getTaskName() 561 { 562 return INFO_TASK_NAME_AUDIT_DATA_SECURITY.get(); 563 } 564 565 566 567 /** 568 * {@inheritDoc} 569 */ 570 @Override() 571 public String getTaskDescription() 572 { 573 return INFO_TASK_DESCRIPTION_AUDIT_DATA_SECURITY.get(); 574 } 575 576 577 578 /** 579 * Retrieves the names of the auditors that should be invoked during the 580 * data security audit. 581 * 582 * @return The names of the include auditors that should be used for the 583 * task, or an empty list if either an exclude list should be used or 584 * all enabled auditors should be used. 585 */ 586 public List<String> getIncludeAuditors() 587 { 588 return includeAuditors; 589 } 590 591 592 593 /** 594 * Retrieves the names of the auditors that should not be invoked during the 595 * audit. 596 * 597 * @return The names of the exclude auditors that should be used for the 598 * task, or an empty list if either an include list should be used or 599 * all enabled auditors should be used. 600 */ 601 public List<String> getExcludeAuditors() 602 { 603 return excludeAuditors; 604 } 605 606 607 608 /** 609 * Retrieves the backend IDs of the backends that should be examined during 610 * the course of the audit. 611 * 612 * @return The backend IDs of the backends that should be examined during the 613 * course of the audit, or an empty list if all backends that support 614 * this capability should be used. 615 */ 616 public List<String> getBackendIDs() 617 { 618 return backendIDs; 619 } 620 621 622 623 /** 624 * Retrieves the string representations of the report filters that should be 625 * used to identify which entries should be examined during the course of the 626 * audit. 627 * 628 * @return The string representations of the report filters that should be 629 * used to identify which entries should be examined during the 630 * course of the audit, or an empty list if all entries should be 631 * examined. 632 */ 633 public List<String> getReportFilterStrings() 634 { 635 return reportFilters; 636 } 637 638 639 640 /** 641 * Retrieves the parsed report filters that should be used to identify which 642 * entries should be examined during the course of the audit. 643 * 644 * @return The parsed report filters that should be used to identify which 645 * entries should be examined during the course of the audit, or an 646 * empty list if all entries should be examined. 647 * 648 * @throws LDAPException If any of the filter strings cannot be parsed as a 649 * valid filter. 650 */ 651 public List<Filter> getReportFilters() 652 throws LDAPException 653 { 654 if (reportFilters.isEmpty()) 655 { 656 return Collections.emptyList(); 657 } 658 659 final ArrayList<Filter> filterList = new ArrayList<>(reportFilters.size()); 660 for (final String filter : reportFilters) 661 { 662 filterList.add(Filter.create(filter)); 663 } 664 return Collections.unmodifiableList(filterList); 665 } 666 667 668 669 /** 670 * Retrieves the path to the directory on the server filesystem in which the 671 * report output files should be written. 672 * 673 * @return The path to the directory on the server filesystem in which the 674 * report output files should be written. 675 */ 676 public String getOutputDirectory() 677 { 678 return outputDirectory; 679 } 680 681 682 683 /** 684 * {@inheritDoc} 685 */ 686 @Override() 687 protected List<String> getAdditionalObjectClasses() 688 { 689 return Collections.singletonList(OC_AUDIT_DATA_SECURITY_TASK); 690 } 691 692 693 694 /** 695 * {@inheritDoc} 696 */ 697 @Override() 698 protected List<Attribute> getAdditionalAttributes() 699 { 700 final LinkedList<Attribute> attrList = new LinkedList<>(); 701 702 if (! includeAuditors.isEmpty()) 703 { 704 attrList.add(new Attribute(ATTR_INCLUDE_AUDITOR, includeAuditors)); 705 } 706 707 if (! excludeAuditors.isEmpty()) 708 { 709 attrList.add(new Attribute(ATTR_EXCLUDE_AUDITOR, excludeAuditors)); 710 } 711 712 if (! backendIDs.isEmpty()) 713 { 714 attrList.add(new Attribute(ATTR_BACKEND_ID, backendIDs)); 715 } 716 717 if (! reportFilters.isEmpty()) 718 { 719 attrList.add(new Attribute(ATTR_REPORT_FILTER, reportFilters)); 720 } 721 722 if (outputDirectory != null) 723 { 724 attrList.add(new Attribute(ATTR_OUTPUT_DIRECTORY, outputDirectory)); 725 } 726 727 return attrList; 728 } 729 730 731 732 /** 733 * {@inheritDoc} 734 */ 735 @Override() 736 public List<TaskProperty> getTaskSpecificProperties() 737 { 738 return Collections.unmodifiableList(Arrays.asList( 739 PROPERTY_INCLUDE_AUDITOR, 740 PROPERTY_EXCLUDE_AUDITOR, 741 PROPERTY_BACKEND_ID, 742 PROPERTY_REPORT_FILTER, 743 PROPERTY_OUTPUT_DIRECTORY)); 744 } 745 746 747 748 /** 749 * {@inheritDoc} 750 */ 751 @Override() 752 public Map<TaskProperty,List<Object>> getTaskPropertyValues() 753 { 754 final LinkedHashMap<TaskProperty,List<Object>> props = 755 new LinkedHashMap<>(StaticUtils.computeMapCapacity(5)); 756 757 if (! includeAuditors.isEmpty()) 758 { 759 props.put(PROPERTY_INCLUDE_AUDITOR, 760 Collections.<Object>unmodifiableList(includeAuditors)); 761 } 762 763 if (! excludeAuditors.isEmpty()) 764 { 765 props.put(PROPERTY_EXCLUDE_AUDITOR, 766 Collections.<Object>unmodifiableList(excludeAuditors)); 767 } 768 769 if (! backendIDs.isEmpty()) 770 { 771 props.put(PROPERTY_BACKEND_ID, 772 Collections.<Object>unmodifiableList(backendIDs)); 773 } 774 775 if (! reportFilters.isEmpty()) 776 { 777 props.put(PROPERTY_REPORT_FILTER, 778 Collections.<Object>unmodifiableList(reportFilters)); 779 } 780 781 if (outputDirectory != null) 782 { 783 props.put(PROPERTY_OUTPUT_DIRECTORY, 784 Collections.<Object>singletonList(outputDirectory)); 785 } 786 787 return Collections.unmodifiableMap(props); 788 } 789 790 791 792 /** 793 * Retrieves an unmodifiable list using information from the provided list. 794 * If the given list is {@code null}, then an empty list will be returned. 795 * Otherwise, an unmodifiable version of the provided list will be returned. 796 * 797 * @param l The list to be processed. 798 * 799 * @return The resulting string list. 800 */ 801 private static List<String> getStringList(final List<String> l) 802 { 803 if (l == null) 804 { 805 return Collections.emptyList(); 806 } 807 else 808 { 809 return Collections.unmodifiableList(l); 810 } 811 } 812}