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