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}