001    /*
002     * Copyright 2010-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2015 UnboundID Corp.
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     */
021    package com.unboundid.ldap.sdk.unboundidds.tasks;
022    
023    
024    
025    import java.util.Arrays;
026    import java.util.Collections;
027    import java.util.Date;
028    import java.util.LinkedHashMap;
029    import java.util.LinkedList;
030    import java.util.List;
031    import java.util.Map;
032    
033    import com.unboundid.ldap.sdk.Attribute;
034    import com.unboundid.ldap.sdk.Entry;
035    import com.unboundid.util.NotMutable;
036    import com.unboundid.util.StaticUtils;
037    import com.unboundid.util.ThreadSafety;
038    import com.unboundid.util.ThreadSafetyLevel;
039    
040    import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*;
041    import static com.unboundid.util.Validator.*;
042    
043    
044    
045    /**
046     * <BLOCKQUOTE>
047     *   <B>NOTE:</B>  This class is part of the Commercial Edition of the UnboundID
048     *   LDAP SDK for Java.  It is not available for use in applications that
049     *   include only the Standard Edition of the LDAP SDK, and is not supported for
050     *   use in conjunction with non-UnboundID products.
051     * </BLOCKQUOTE>
052     * This class defines a Directory Server task that can be used to cause the
053     * server to generate administrative alerts, or to manage the set of degraded or
054     * unavailable alert types.
055     * <BR><BR>
056     * The properties that are available for use with this type of task include:
057     * <UL>
058     *   <LI>The alert type of the alert notification to generate.  If this is
059     *       provided, then an alert message must also be provided.</LI>
060     *   <LI>The alert message for the alert notification to generate.  If this is
061     *       provided, then an alert type must also be provided.</LI>
062     *   <LI>The names of the alert types to add to the set of degraded alert types
063     *       in the general monitor entry.</LI>
064     *   <LI>The names of the alert types to remove from the set of degraded alert
065     *       types in the general monitor entry.</LI>
066     *   <LI>The names of the alert types to add to the set of unavailable alert
067     *       types in the general monitor entry.</LI>
068     *   <LI>The names of the alert types to remove from the set of unavailable
069     *       alert types in the general monitor entry.</LI>
070     * </UL>
071     */
072    @NotMutable()
073    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
074    public final class AlertTask
075           extends Task
076    {
077      /**
078       * The fully-qualified name of the Java class that is used for the alert task.
079       */
080      static final String ALERT_TASK_CLASS =
081           "com.unboundid.directory.server.tasks.AlertTask";
082    
083    
084    
085      /**
086       * The name of the attribute used to specify the alert type for the alert to
087       * generate.
088       */
089      private static final String ATTR_ALERT_TYPE = "ds-task-alert-type";
090    
091    
092    
093      /**
094       * The name of the attribute used to specify the message for the alert to
095       * generate.
096       */
097      private static final String ATTR_ALERT_MESSAGE = "ds-task-alert-message";
098    
099    
100    
101      /**
102       * The name of the attribute used to specify the alert type(s) to add to the
103       * set of degraded alert types.
104       */
105      private static final String ATTR_ADD_DEGRADED_TYPE =
106           "ds-task-alert-add-degraded-type";
107    
108    
109    
110      /**
111       * The name of the attribute used to specify the alert type(s) to remove from
112       * the set of degraded alert types.
113       */
114      private static final String ATTR_REMOVE_DEGRADED_TYPE =
115           "ds-task-alert-remove-degraded-type";
116    
117    
118    
119      /**
120       * The name of the attribute used to specify the alert type(s) to add to the
121       * set of unavailable alert types.
122       */
123      private static final String ATTR_ADD_UNAVAILABLE_TYPE =
124           "ds-task-alert-add-unavailable-type";
125    
126    
127    
128      /**
129       * The name of the attribute used to specify the alert type(s) to remove from
130       * the set of unavailable alert types.
131       */
132      private static final String ATTR_REMOVE_UNAVAILABLE_TYPE =
133           "ds-task-alert-remove-unavailable-type";
134    
135    
136    
137      /**
138       * The name of the object class used in alert task entries.
139       */
140      private static final String OC_ALERT_TASK = "ds-task-alert";
141    
142    
143    
144      /**
145       * The task property that will be used for the alert type.
146       */
147      private static final TaskProperty PROPERTY_ALERT_TYPE =
148         new TaskProperty(ATTR_ALERT_TYPE, INFO_ALERT_DISPLAY_NAME_TYPE.get(),
149              INFO_ALERT_DESCRIPTION_TYPE.get(), String.class, false, false,
150              false);
151    
152    
153    
154      /**
155       * The task property that will be used for the alert message.
156       */
157      private static final TaskProperty PROPERTY_ALERT_MESSAGE =
158         new TaskProperty(ATTR_ALERT_MESSAGE, INFO_ALERT_DISPLAY_NAME_MESSAGE.get(),
159              INFO_ALERT_DESCRIPTION_MESSAGE.get(), String.class, false, false,
160              false);
161    
162    
163    
164      /**
165       * The task property that will be used for the add degraded alert types.
166       */
167      private static final TaskProperty PROPERTY_ADD_DEGRADED_TYPE =
168         new TaskProperty(ATTR_ADD_DEGRADED_TYPE,
169              INFO_ALERT_DISPLAY_NAME_ADD_DEGRADED.get(),
170              INFO_ALERT_DESCRIPTION_ADD_DEGRADED.get(), String.class, false, true,
171              false);
172    
173    
174    
175      /**
176       * The task property that will be used for the remove degraded alert types.
177       */
178      private static final TaskProperty PROPERTY_REMOVE_DEGRADED_TYPE =
179         new TaskProperty(ATTR_REMOVE_DEGRADED_TYPE,
180              INFO_ALERT_DISPLAY_NAME_REMOVE_DEGRADED.get(),
181              INFO_ALERT_DESCRIPTION_REMOVE_DEGRADED.get(), String.class, false,
182              true, false);
183    
184    
185    
186      /**
187       * The task property that will be used for the add unavailable alert types.
188       */
189      private static final TaskProperty PROPERTY_ADD_UNAVAILABLE_TYPE =
190         new TaskProperty(ATTR_ADD_UNAVAILABLE_TYPE,
191              INFO_ALERT_DISPLAY_NAME_ADD_UNAVAILABLE.get(),
192              INFO_ALERT_DESCRIPTION_ADD_UNAVAILABLE.get(), String.class, false,
193              true, false);
194    
195    
196    
197      /**
198       * The task property that will be used for the remove unavailable alert types.
199       */
200      private static final TaskProperty PROPERTY_REMOVE_UNAVAILABLE_TYPE =
201         new TaskProperty(ATTR_REMOVE_UNAVAILABLE_TYPE,
202              INFO_ALERT_DISPLAY_NAME_REMOVE_UNAVAILABLE.get(),
203              INFO_ALERT_DESCRIPTION_REMOVE_UNAVAILABLE.get(), String.class, false,
204              true, false);
205    
206    
207    
208      /**
209       * The serial version UID for this serializable class.
210       */
211      private static final long serialVersionUID = 8253375533166941221L;
212    
213    
214    
215      // The alert types to add to the set of degraded alert types.
216      private final List<String> addDegradedTypes;
217    
218      // The alert types to add to the set of unavailable alert types.
219      private final List<String> addUnavailableTypes;
220    
221      // The alert types to remove from the set of degraded alert types.
222      private final List<String> removeDegradedTypes;
223    
224      // The alert types to remove from the set of unavailable alert types.
225      private final List<String> removeUnavailableTypes;
226    
227      // The message for the alert to be generated.
228      private final String alertMessage;
229    
230      // The name of the alert type for the alert to be generated.
231      private final String alertType;
232    
233    
234    
235      /**
236       * Creates a new uninitialized alert task instance which should only be used
237       * for obtaining general information about this task, including the task name,
238       * description, and supported properties.  Attempts to use a task created with
239       * this constructor for any other reason will likely fail.
240       */
241      public AlertTask()
242      {
243        alertType              = null;
244        alertMessage           = null;
245        addDegradedTypes       = null;
246        addUnavailableTypes    = null;
247        removeDegradedTypes    = null;
248        removeUnavailableTypes = null;
249      }
250    
251    
252    
253    
254      /**
255       * Creates a new alert task that can be used to generate an administrative
256       * alert with the provided information.
257       *
258       * @param  alertType     The alert type to use for the generated alert.  It
259       *                       must not be {@code null}.
260       * @param  alertMessage  The message to use for the generated alert.  It must
261       *                       not be {@code null}.
262       */
263      public AlertTask(final String alertType, final String alertMessage)
264      {
265        this(null, alertType, alertMessage, null, null, null, null, null, null,
266             null, null, null);
267      }
268    
269    
270    
271      /**
272       * Creates a new alert task that can be used to generate an administrative
273       * alert and/or update the set of degraded or unavailable alert types for the
274       * Directory Server.  At least one element must be provided.
275       *
276       * @param  alertType               The alert type to use for the generated
277       *                                 alert.  It may be {@code null} if no alert
278       *                                 should be generated, but if it is
279       *                                 non-{@code null} then the alert message
280       *                                 must also be non-{@code null}.
281       * @param  alertMessage            The message to use for the generated alert.
282       *                                 It may be {@code null} if no alert should
283       *                                 be generated, but if it is non-{@code null}
284       *                                 then the alert type must also be
285       *                                 non-{@code null}.
286       * @param  addDegradedTypes        The names of the alert types to add to the
287       *                                 Directory Server's set of degraded alert
288       *                                 types.  It may be {@code null} or empty if
289       *                                 no degraded alert types should be added.
290       * @param  removeDegradedTypes     The names of the alert types to remove from
291       *                                 the Directory Server's set of degraded
292       *                                 alert types.  It may be {@code null} or
293       *                                 empty if no degraded alert types should be
294       *                                 removed.
295       * @param  addUnavailableTypes     The names of the alert types to add to the
296       *                                 Directory Server's set of unavailable alert
297       *                                 types.  It may be {@code null} or empty if
298       *                                 no unavailable alert types should be added.
299       * @param  removeUnavailableTypes  The names of the alert types to remove from
300       *                                 the Directory Server's set of unavailable
301       *                                 alert types.  It may be {@code null} or
302       *                                 empty if no unavailable alert types should
303       *                                 be removed.
304       */
305      public AlertTask(final String alertType, final String alertMessage,
306                       final List<String> addDegradedTypes,
307                       final List<String> removeDegradedTypes,
308                       final List<String> addUnavailableTypes,
309                       final List<String> removeUnavailableTypes)
310      {
311        this(null, alertType, alertMessage, addDegradedTypes, removeDegradedTypes,
312             addUnavailableTypes, removeUnavailableTypes, null, null, null,
313             null, null);
314      }
315    
316    
317    
318      /**
319       * Creates a new alert task that can be used to generate an administrative
320       * alert and/or update the set of degraded or unavailable alert types for the
321       * Directory Server.  At least one alert-related element must be provided.
322       *
323       * @param  taskID                  The task ID to use for this task.  If it is
324       *                                 {@code null} then a UUID will be generated
325       *                                 for use as the task ID.
326       * @param  alertType               The alert type to use for the generated
327       *                                 alert.  It may be {@code null} if no alert
328       *                                 should be generated, but if it is
329       *                                 non-{@code null} then the alert message
330       *                                 must also be non-{@code null}.
331       * @param  alertMessage            The message to use for the generated alert.
332       *                                 It may be {@code null} if no alert should
333       *                                 be generated, but if it is non-{@code null}
334       *                                 then the alert type must also be
335       *                                 non-{@code null}.
336       * @param  addDegradedTypes        The names of the alert types to add to the
337       *                                 Directory Server's set of degraded alert
338       *                                 types.  It may be {@code null} or empty if
339       *                                 no degraded alert types should be added.
340       * @param  removeDegradedTypes     The names of the alert types to remove from
341       *                                 the Directory Server's set of degraded
342       *                                 alert types.  It may be {@code null} or
343       *                                 empty if no degraded alert types should be
344       *                                 removed.
345       * @param  addUnavailableTypes     The names of the alert types to add to the
346       *                                 Directory Server's set of unavailable alert
347       *                                 types.  It may be {@code null} or empty if
348       *                                 no unavailable alert types should be added.
349       * @param  removeUnavailableTypes  The names of the alert types to remove from
350       *                                 the Directory Server's set of unavailable
351       *                                 alert types.  It may be {@code null} or
352       *                                 empty if no unavailable alert types should
353       *                                 be removed.
354       * @param  scheduledStartTime      The time that this task should start
355       *                                 running.
356       * @param  dependencyIDs           The list of task IDs that will be required
357       *                                 to complete before this task will be
358       *                                 eligible to start.
359       * @param  failedDependencyAction  Indicates what action should be taken if
360       *                                 any of the dependencies for this task do
361       *                                 not complete successfully.
362       * @param  notifyOnCompletion      The list of e-mail addresses of individuals
363       *                                 that should be notified when this task
364       *                                 completes.
365       * @param  notifyOnError           The list of e-mail addresses of individuals
366       *                                 that should be notified if this task does
367       *                                 not complete successfully.
368       */
369      public AlertTask(final String taskID, final String alertType,
370                       final String alertMessage,
371                       final List<String> addDegradedTypes,
372                       final List<String> removeDegradedTypes,
373                       final List<String> addUnavailableTypes,
374                       final List<String> removeUnavailableTypes,
375                       final Date scheduledStartTime,
376                       final List<String> dependencyIDs,
377                       final FailedDependencyAction failedDependencyAction,
378                       final List<String> notifyOnCompletion,
379                       final List<String> notifyOnError)
380      {
381        super(taskID, ALERT_TASK_CLASS, scheduledStartTime, dependencyIDs,
382             failedDependencyAction, notifyOnCompletion, notifyOnError);
383    
384        this.alertType    = alertType;
385        this.alertMessage = alertMessage;
386    
387        ensureTrue((alertType == null) == (alertMessage == null));
388    
389    
390        this.addDegradedTypes       = getStringList(addDegradedTypes);
391        this.removeDegradedTypes    = getStringList(removeDegradedTypes);
392        this.addUnavailableTypes    = getStringList(addUnavailableTypes);
393        this.removeUnavailableTypes = getStringList(removeUnavailableTypes);
394    
395        if (alertType == null)
396        {
397          ensureFalse(this.addDegradedTypes.isEmpty() &&
398               this.removeDegradedTypes.isEmpty() &&
399               this.addUnavailableTypes.isEmpty() &&
400               this.removeUnavailableTypes.isEmpty());
401        }
402      }
403    
404    
405    
406      /**
407       * Creates a new alert task from the provided entry.
408       *
409       * @param  entry  The entry to use to create this alert task.
410       *
411       * @throws  TaskException  If the provided entry cannot be parsed as an alert
412       *                         task entry.
413       */
414      public AlertTask(final Entry entry)
415             throws TaskException
416      {
417        super(entry);
418    
419    
420        // Get the alert type and message.  If either is present, then both must be.
421        alertType    = entry.getAttributeValue(ATTR_ALERT_TYPE);
422        alertMessage = entry.getAttributeValue(ATTR_ALERT_MESSAGE);
423    
424        if ((alertType == null) != (alertMessage == null))
425        {
426          throw new TaskException(ERR_ALERT_TYPE_AND_MESSAGE_INTERDEPENDENT.get());
427        }
428    
429    
430        // Get the values to add/remove from the degraded/unavailable alert types.
431        addDegradedTypes       = parseStringList(entry, ATTR_ADD_DEGRADED_TYPE);
432        removeDegradedTypes    = parseStringList(entry, ATTR_REMOVE_DEGRADED_TYPE);
433        addUnavailableTypes    = parseStringList(entry, ATTR_ADD_UNAVAILABLE_TYPE);
434        removeUnavailableTypes = parseStringList(entry,
435             ATTR_REMOVE_UNAVAILABLE_TYPE);
436    
437        if ((alertType == null) && addDegradedTypes.isEmpty() &&
438            removeDegradedTypes.isEmpty() && addUnavailableTypes.isEmpty() &&
439            removeUnavailableTypes.isEmpty())
440        {
441          throw new TaskException(ERR_ALERT_ENTRY_NO_ELEMENTS.get());
442        }
443      }
444    
445    
446    
447      /**
448       * Creates a new alert task from the provided set of task properties.
449       *
450       * @param  properties  The set of task properties and their corresponding
451       *                     values to use for the task.  It must not be
452       *                     {@code null}.
453       *
454       * @throws  TaskException  If the provided set of properties cannot be used to
455       *                         create a valid alert task.
456       */
457      public AlertTask(final Map<TaskProperty,List<Object>> properties)
458             throws TaskException
459      {
460        super(ALERT_TASK_CLASS, properties);
461    
462        String type = null;
463        String message = null;
464        final LinkedList<String> addDegraded = new LinkedList<String>();
465        final LinkedList<String> removeDegraded = new LinkedList<String>();
466        final LinkedList<String> addUnavailable = new LinkedList<String>();
467        final LinkedList<String> removeUnavailable = new LinkedList<String>();
468        for (final Map.Entry<TaskProperty,List<Object>> entry :
469             properties.entrySet())
470        {
471          final TaskProperty p = entry.getKey();
472          final String attrName = StaticUtils.toLowerCase(p.getAttributeName());
473          final List<Object> values = entry.getValue();
474    
475          if (attrName.equals(ATTR_ALERT_TYPE))
476          {
477            type = parseString(p, values, type);
478          }
479          else if (attrName.equals(ATTR_ALERT_MESSAGE))
480          {
481            message = parseString(p, values, message);
482          }
483          else if (attrName.equals(ATTR_ADD_DEGRADED_TYPE))
484          {
485            final String[] s = parseStrings(p, values, null);
486            if (s != null)
487            {
488              addDegraded.addAll(Arrays.asList(s));
489            }
490          }
491          else if (attrName.equals(ATTR_REMOVE_DEGRADED_TYPE))
492          {
493            final String[] s = parseStrings(p, values, null);
494            if (s != null)
495            {
496              removeDegraded.addAll(Arrays.asList(s));
497            }
498          }
499          else if (attrName.equals(ATTR_ADD_UNAVAILABLE_TYPE))
500          {
501            final String[] s = parseStrings(p, values, null);
502            if (s != null)
503            {
504              addUnavailable.addAll(Arrays.asList(s));
505            }
506          }
507          else if (attrName.equals(ATTR_REMOVE_UNAVAILABLE_TYPE))
508          {
509            final String[] s = parseStrings(p, values, null);
510            if (s != null)
511            {
512              removeUnavailable.addAll(Arrays.asList(s));
513            }
514          }
515        }
516    
517        alertType              = type;
518        alertMessage           = message;
519        addDegradedTypes       = Collections.unmodifiableList(addDegraded);
520        removeDegradedTypes    = Collections.unmodifiableList(removeDegraded);
521        addUnavailableTypes    = Collections.unmodifiableList(addUnavailable);
522        removeUnavailableTypes = Collections.unmodifiableList(removeUnavailable);
523    
524        if ((alertType == null) != (alertMessage == null))
525        {
526          throw new TaskException(ERR_ALERT_TYPE_AND_MESSAGE_INTERDEPENDENT.get());
527        }
528    
529        if ((alertType == null) && addDegradedTypes.isEmpty() &&
530            removeDegradedTypes.isEmpty() && addUnavailableTypes.isEmpty() &&
531            removeUnavailableTypes.isEmpty())
532        {
533          throw new TaskException(ERR_ALERT_PROPERTIES_NO_ELEMENTS.get());
534        }
535      }
536    
537    
538    
539      /**
540       * {@inheritDoc}
541       */
542      @Override()
543      public String getTaskName()
544      {
545        return INFO_TASK_NAME_ALERT.get();
546      }
547    
548    
549    
550      /**
551       * {@inheritDoc}
552       */
553      @Override()
554      public String getTaskDescription()
555      {
556        return INFO_TASK_DESCRIPTION_ALERT.get();
557      }
558    
559    
560    
561      /**
562       * Retrieves the name of the alert type to use for the alert notification to
563       * be generated, if appropriate.
564       *
565       * @return  The name of the alert type to use for the alert notification to be
566       *          generated, or {@code null} if no alert should be generated.
567       */
568      public String getAlertType()
569      {
570        return alertType;
571      }
572    
573    
574    
575      /**
576       * Retrieves the message to use for the alert notification to be generated, if
577       * appropriate.
578       *
579       * @return  The message to use for the alert notification to be generated, or
580       *          {@code null} if no alert should be generated.
581       */
582      public String getAlertMessage()
583      {
584        return alertMessage;
585      }
586    
587    
588    
589      /**
590       * Retrieves the names of the alert types that should be added to the set of
591       * degraded alert types.
592       *
593       * @return  The names of the alert types that should be added to the set of
594       *          degraded alert types, or an empty list if no degraded alert types
595       *          should be added.
596       */
597      public List<String> getAddDegradedAlertTypes()
598      {
599        return addDegradedTypes;
600      }
601    
602    
603    
604      /**
605       * Retrieves the names of the alert types that should be removed from the set
606       * of degraded alert types.
607       *
608       * @return  The names of the alert types that should be removed from the set
609       *          of degraded alert types, or an empty list if no degraded alert
610       *          types should be removed.
611       */
612      public List<String> getRemoveDegradedAlertTypes()
613      {
614        return removeDegradedTypes;
615      }
616    
617    
618    
619      /**
620       * Retrieves the names of the alert types that should be added to the set of
621       * unavailable alert types.
622       *
623       * @return  The names of the alert types that should be added to the set of
624       *          unavailable alert types, or an empty list if no unavailable alert
625       *          types should be added.
626       */
627      public List<String> getAddUnavailableAlertTypes()
628      {
629        return addUnavailableTypes;
630      }
631    
632    
633    
634      /**
635       * Retrieves the names of the alert types that should be removed from the set
636       * of unavailable alert types.
637       *
638       * @return  The names of the alert types that should be removed from the set
639       *          of unavailable alert types, or an empty list if no unavailable
640       *          alert types should be removed.
641       */
642      public List<String> getRemoveUnavailableAlertTypes()
643      {
644        return removeUnavailableTypes;
645      }
646    
647    
648    
649      /**
650       * {@inheritDoc}
651       */
652      @Override()
653      protected List<String> getAdditionalObjectClasses()
654      {
655        return Arrays.asList(OC_ALERT_TASK);
656      }
657    
658    
659    
660      /**
661       * {@inheritDoc}
662       */
663      @Override()
664      protected List<Attribute> getAdditionalAttributes()
665      {
666        final LinkedList<Attribute> attrList = new LinkedList<Attribute>();
667    
668        if (alertType != null)
669        {
670          attrList.add(new Attribute(ATTR_ALERT_TYPE, alertType));
671          attrList.add(new Attribute(ATTR_ALERT_MESSAGE, alertMessage));
672        }
673    
674        if (! addDegradedTypes.isEmpty())
675        {
676          attrList.add(new Attribute(ATTR_ADD_DEGRADED_TYPE, addDegradedTypes));
677        }
678    
679        if (! removeDegradedTypes.isEmpty())
680        {
681          attrList.add(new Attribute(ATTR_REMOVE_DEGRADED_TYPE,
682               removeDegradedTypes));
683        }
684    
685        if (! addUnavailableTypes.isEmpty())
686        {
687          attrList.add(new Attribute(ATTR_ADD_UNAVAILABLE_TYPE,
688               addUnavailableTypes));
689        }
690    
691        if (! removeUnavailableTypes.isEmpty())
692        {
693          attrList.add(new Attribute(ATTR_REMOVE_UNAVAILABLE_TYPE,
694               removeUnavailableTypes));
695        }
696    
697        return attrList;
698      }
699    
700    
701    
702      /**
703       * {@inheritDoc}
704       */
705      @Override()
706      public List<TaskProperty> getTaskSpecificProperties()
707      {
708        return Collections.unmodifiableList(Arrays.asList(
709             PROPERTY_ALERT_TYPE, PROPERTY_ALERT_MESSAGE,
710             PROPERTY_ADD_DEGRADED_TYPE, PROPERTY_REMOVE_DEGRADED_TYPE,
711             PROPERTY_ADD_UNAVAILABLE_TYPE, PROPERTY_REMOVE_UNAVAILABLE_TYPE));
712      }
713    
714    
715    
716      /**
717       * {@inheritDoc}
718       */
719      @Override()
720      public Map<TaskProperty,List<Object>> getTaskPropertyValues()
721      {
722        final LinkedHashMap<TaskProperty,List<Object>> props =
723             new LinkedHashMap<TaskProperty,List<Object>>(6);
724    
725        if (alertType != null)
726        {
727          props.put(PROPERTY_ALERT_TYPE,
728               Collections.<Object>unmodifiableList(Arrays.asList(alertType)));
729          props.put(PROPERTY_ALERT_MESSAGE,
730               Collections.<Object>unmodifiableList(Arrays.asList(alertMessage)));
731        }
732    
733        if (! addDegradedTypes.isEmpty())
734        {
735          props.put(PROPERTY_ADD_DEGRADED_TYPE,
736               Collections.<Object>unmodifiableList(addDegradedTypes));
737        }
738    
739        if (! removeDegradedTypes.isEmpty())
740        {
741          props.put(PROPERTY_REMOVE_DEGRADED_TYPE,
742               Collections.<Object>unmodifiableList(removeDegradedTypes));
743        }
744    
745        if (! addUnavailableTypes.isEmpty())
746        {
747          props.put(PROPERTY_ADD_UNAVAILABLE_TYPE,
748               Collections.<Object>unmodifiableList(addUnavailableTypes));
749        }
750    
751        if (! removeUnavailableTypes.isEmpty())
752        {
753          props.put(PROPERTY_REMOVE_UNAVAILABLE_TYPE,
754               Collections.<Object>unmodifiableList(removeUnavailableTypes));
755        }
756    
757        return Collections.unmodifiableMap(props);
758      }
759    
760    
761    
762      /**
763       * Retrieves an unmodifiable list using information from the provided list.
764       * If the given list is {@code null}, then an empty list will be returned.
765       * Otherwise, an unmodifiable version of the provided list will be returned.
766       *
767       * @param  l  The list to be processed.
768       *
769       * @return  The resulting string list.
770       */
771      private static List<String> getStringList(final List<String> l)
772      {
773        if (l == null)
774        {
775          return Collections.emptyList();
776        }
777        else
778        {
779          return Collections.unmodifiableList(l);
780        }
781      }
782    }