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