001/*
002 * Copyright 2008-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2019 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.monitors;
022
023
024
025import java.io.Serializable;
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.Date;
029import java.util.Iterator;
030import java.util.LinkedHashMap;
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.ReadOnlyEntry;
037import com.unboundid.util.Debug;
038import com.unboundid.util.DebugType;
039import com.unboundid.util.NotExtensible;
040import com.unboundid.util.StaticUtils;
041import com.unboundid.util.ThreadSafety;
042import com.unboundid.util.ThreadSafetyLevel;
043import com.unboundid.util.Validator;
044
045import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*;
046
047
048
049/**
050 * This class defines a generic monitor entry that provides access to monitor
051 * information provided by a Ping Identity, UnboundID, or Nokia/Alcatel-Lucent
052 * 8661 server instance.  Subclasses may provide specific methods for
053 * interpreting the information exposed by specific types of monitor entries.
054 * <BR>
055 * <BLOCKQUOTE>
056 *   <B>NOTE:</B>  This class, and other classes within the
057 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
058 *   supported for use against Ping Identity, UnboundID, and
059 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
060 *   for proprietary functionality or for external specifications that are not
061 *   considered stable or mature enough to be guaranteed to work in an
062 *   interoperable way with other types of LDAP servers.
063 * </BLOCKQUOTE>
064 * <BR>
065 * See the {@link MonitorManager} class for an example that demonstrates the
066 * process for retrieving all monitor entries available in the directory server
067 * and retrieving the information they provide using the generic API.
068 */
069@NotExtensible()
070@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
071public class MonitorEntry
072       implements Serializable
073{
074  /**
075   * The object class used for all monitor entries.  Specific monitor entries
076   * will have a subclass of this class.
077   */
078  static final String GENERIC_MONITOR_OC = "ds-monitor-entry";
079
080
081
082  /**
083   * The base DN for all monitor entries.
084   */
085  static final String MONITOR_BASE_DN = "cn=monitor";
086
087
088
089  /**
090   * The name of the attribute used to hold the name assigned to the monitor
091   * entry.
092   */
093  private static final String ATTR_MONITOR_NAME = "cn";
094
095
096
097  /**
098   * The serial version UID for this serializable class.
099   */
100  private static final long serialVersionUID = -8889119758772055683L;
101
102
103
104  // The entry containing the information used by this monitor entry object.
105  private final ReadOnlyEntry entry;
106
107  // The monitor object class for the associated monitor entry, if available.
108  private final String monitorClass;
109
110  // The monitor name for this monitor entry.
111  private final String monitorName;
112
113
114
115  /**
116   * Creates a new monitor entry from the information contained in the provided
117   * entry.
118   *
119   * @param  entry  The entry providing information to use for this monitor
120   *                entry.  It must not be {@code null}.
121   */
122  public MonitorEntry(final Entry entry)
123  {
124    Validator.ensureNotNull(entry);
125
126    this.entry = new ReadOnlyEntry(entry);
127
128    monitorClass = getMonitorClass(entry);
129    monitorName  = getString(ATTR_MONITOR_NAME);
130  }
131
132
133
134  /**
135   * Retrieves the DN for this monitor entry.
136   *
137   * @return  The DN for this monitor entry.
138   */
139  public final String getDN()
140  {
141    return entry.getDN();
142  }
143
144
145
146  /**
147   * Retrieves the {@code Entry} used to create this monitor entry.
148   *
149   * @return  The {@code Entry} used to create this monitor entry.
150   */
151  public final ReadOnlyEntry getEntry()
152  {
153    return entry;
154  }
155
156
157
158  /**
159   * Retrieves the name of the structural object class for this monitor entry.
160   *
161   * @return  The name of the structural object class for this monitor entry, or
162   *          the generic monitor object class if no appropriate subclass could
163   *          be identified.
164   */
165  public final String getMonitorClass()
166  {
167    return monitorClass;
168  }
169
170
171
172  /**
173   * Retrieves the monitor name for this monitor entry.
174   *
175   * @return  The monitor name for this monitor entry, or {@code null} if it was
176   *          not included in the monitor entry.
177   */
178  public final String getMonitorName()
179  {
180    return monitorName;
181  }
182
183
184
185  /**
186   * Retrieves a human-readable display name for this monitor entry.
187   *
188   * @return  A human-readable display name for this monitor entry.
189   */
190  public String getMonitorDisplayName()
191  {
192    return INFO_GENERIC_MONITOR_DISPNAME.get();
193  }
194
195
196
197  /**
198   * Retrieves a human-readable description name for this monitor entry.
199   *
200   * @return  A human-readable description name for this monitor entry.
201   */
202  public String getMonitorDescription()
203  {
204    return INFO_GENERIC_MONITOR_DESC.get();
205  }
206
207
208
209  /**
210   * Retrieves the set of parsed monitor attributes for this monitor entry,
211   * mapped from a unique identifier (in all lowercase characters) to the
212   * corresponding monitor attribute.
213   *
214   * @return  The set of parsed monitor attributes for this monitor entry.
215   */
216  public Map<String,MonitorAttribute> getMonitorAttributes()
217  {
218    // Retrieve a map of all attributes in the entry except cn and objectClass.
219    final LinkedHashMap<String,MonitorAttribute> attrs =
220         new LinkedHashMap<>(StaticUtils.computeMapCapacity(20));
221
222    for (final Attribute a : entry.getAttributes())
223    {
224      final String lowerName = StaticUtils.toLowerCase(a.getName());
225      if (lowerName.equals("cn") || lowerName.equals("objectclass"))
226      {
227        continue;
228      }
229
230      attrs.put(lowerName,
231           new MonitorAttribute(lowerName, a.getName(), "", a.getValues()));
232    }
233
234    return Collections.unmodifiableMap(attrs);
235  }
236
237
238
239  /**
240   * Creates a monitor entry object from the provided entry.  An attempt will be
241   * made to decode the entry as an instance of the most appropriate subclass,
242   * but if that is not possible then it will be parsed as a generic monitor
243   * entry.
244   *
245   * @param  entry  The entry to be decoded as a monitor entry.
246   *
247   * @return  The decoded monitor entry of the appropriate subtype, or a generic
248   *          monitor entry if no appropriate subclass could be identified.
249   */
250  public static MonitorEntry decode(final Entry entry)
251  {
252    final String monitorClass = getMonitorClass(entry);
253
254    if (monitorClass.equalsIgnoreCase(
255             ActiveOperationsMonitorEntry.ACTIVE_OPERATIONS_MONITOR_OC))
256    {
257      return new ActiveOperationsMonitorEntry(entry);
258    }
259    else if (monitorClass.equalsIgnoreCase(
260                  BackendMonitorEntry.BACKEND_MONITOR_OC))
261    {
262      return new BackendMonitorEntry(entry);
263    }
264    else if (monitorClass.equalsIgnoreCase(
265                  ClientConnectionMonitorEntry.CLIENT_CONNECTION_MONITOR_OC))
266    {
267      return new ClientConnectionMonitorEntry(entry);
268    }
269    else if (monitorClass.equalsIgnoreCase(
270                  ConnectionHandlerMonitorEntry.CONNECTION_HANDLER_MONITOR_OC))
271    {
272      return new ConnectionHandlerMonitorEntry(entry);
273    }
274    else if (monitorClass.equalsIgnoreCase(
275                  DiskSpaceUsageMonitorEntry.DISK_SPACE_USAGE_MONITOR_OC))
276    {
277      return new DiskSpaceUsageMonitorEntry(entry);
278    }
279    else if (monitorClass.equalsIgnoreCase(
280                  EntryCacheMonitorEntry.ENTRY_CACHE_MONITOR_OC))
281    {
282      return new EntryCacheMonitorEntry(entry);
283    }
284    else if (monitorClass.equalsIgnoreCase(
285                  FIFOEntryCacheMonitorEntry.FIFO_ENTRY_CACHE_MONITOR_OC))
286    {
287      return new FIFOEntryCacheMonitorEntry(entry);
288    }
289    else if (monitorClass.equalsIgnoreCase(
290                  GaugeMonitorEntry.GAUGE_MONITOR_OC))
291    {
292      return new GaugeMonitorEntry(entry);
293    }
294    else if (monitorClass.equalsIgnoreCase(
295                  GeneralMonitorEntry.GENERAL_MONITOR_OC))
296    {
297      return new GeneralMonitorEntry(entry);
298    }
299    else if (monitorClass.equalsIgnoreCase(
300                  GroupCacheMonitorEntry.GROUP_CACHE_MONITOR_OC))
301    {
302      return new GroupCacheMonitorEntry(entry);
303    }
304    else if (monitorClass.equalsIgnoreCase(
305         HostSystemRecentCPUAndMemoryMonitorEntry.
306              HOST_SYSTEM_RECENT_CPU_AND_MEMORY_MONITOR_OC))
307    {
308      return new HostSystemRecentCPUAndMemoryMonitorEntry(entry);
309    }
310    else if (monitorClass.equalsIgnoreCase(
311                  IndexMonitorEntry.INDEX_MONITOR_OC))
312    {
313      return new IndexMonitorEntry(entry);
314    }
315    else if (monitorClass.equalsIgnoreCase(
316                  IndicatorGaugeMonitorEntry.INDICATOR_GAUGE_MONITOR_OC))
317    {
318      return new IndicatorGaugeMonitorEntry(entry);
319    }
320    else if (monitorClass.equalsIgnoreCase(
321                  JEEnvironmentMonitorEntry.JE_ENVIRONMENT_MONITOR_OC))
322    {
323      return new JEEnvironmentMonitorEntry(entry);
324    }
325    else if (monitorClass.equalsIgnoreCase(
326         LDAPExternalServerMonitorEntry.LDAP_EXTERNAL_SERVER_MONITOR_OC))
327    {
328      return new LDAPExternalServerMonitorEntry(entry);
329    }
330    else if (monitorClass.equalsIgnoreCase(
331                  LDAPStatisticsMonitorEntry.LDAP_STATISTICS_MONITOR_OC))
332    {
333      return new LDAPStatisticsMonitorEntry(entry);
334    }
335    else if (monitorClass.equalsIgnoreCase(
336         LoadBalancingAlgorithmMonitorEntry.
337              LOAD_BALANCING_ALGORITHM_MONITOR_OC))
338    {
339      return new LoadBalancingAlgorithmMonitorEntry(entry);
340    }
341    else if (monitorClass.equalsIgnoreCase(
342                  MemoryUsageMonitorEntry.MEMORY_USAGE_MONITOR_OC))
343    {
344      return new MemoryUsageMonitorEntry(entry);
345    }
346    else if (monitorClass.equalsIgnoreCase(
347                  NumericGaugeMonitorEntry.NUMERIC_GAUGE_MONITOR_OC))
348    {
349      return new NumericGaugeMonitorEntry(entry);
350    }
351    else if (monitorClass.equalsIgnoreCase(
352                  PerApplicationProcessingTimeHistogramMonitorEntry.
353                       PER_APPLICATION_PROCESSING_TIME_HISTOGRAM_MONITOR_OC))
354    {
355      return new PerApplicationProcessingTimeHistogramMonitorEntry(entry);
356    }
357    else if (monitorClass.equalsIgnoreCase(
358                  ProcessingTimeHistogramMonitorEntry.
359                       PROCESSING_TIME_HISTOGRAM_MONITOR_OC))
360    {
361      return new ProcessingTimeHistogramMonitorEntry(entry);
362    }
363    else if (monitorClass.equalsIgnoreCase(
364                  ReplicaMonitorEntry.REPLICA_MONITOR_OC))
365    {
366      return new ReplicaMonitorEntry(entry);
367    }
368    else if (monitorClass.equalsIgnoreCase(
369                  ReplicationServerMonitorEntry.REPLICATION_SERVER_MONITOR_OC))
370    {
371      return new ReplicationServerMonitorEntry(entry);
372    }
373    else if (monitorClass.equalsIgnoreCase(
374                  ReplicationSummaryMonitorEntry.
375                       REPLICATION_SUMMARY_MONITOR_OC))
376    {
377      return new ReplicationSummaryMonitorEntry(entry);
378    }
379    else if (monitorClass.equalsIgnoreCase(
380                  ResultCodeMonitorEntry.RESULT_CODE_MONITOR_OC))
381    {
382      return new ResultCodeMonitorEntry(entry);
383    }
384    else if (monitorClass.equalsIgnoreCase(
385                  StackTraceMonitorEntry.STACK_TRACE_MONITOR_OC))
386    {
387      return new StackTraceMonitorEntry(entry);
388    }
389    else if (monitorClass.equalsIgnoreCase(
390                  SystemInfoMonitorEntry.SYSTEM_INFO_MONITOR_OC))
391    {
392      return new SystemInfoMonitorEntry(entry);
393    }
394    else if (monitorClass.equalsIgnoreCase(
395                  TraditionalWorkQueueMonitorEntry.
396                       TRADITIONAL_WORK_QUEUE_MONITOR_OC))
397    {
398      return new TraditionalWorkQueueMonitorEntry(entry);
399    }
400    else if (monitorClass.equalsIgnoreCase(
401                  UnboundIDWorkQueueMonitorEntry.
402                       UNBOUNDID_WORK_QUEUE_MONITOR_OC))
403    {
404      return new UnboundIDWorkQueueMonitorEntry(entry);
405    }
406    else if (monitorClass.equalsIgnoreCase(
407                  VersionMonitorEntry.VERSION_MONITOR_OC))
408    {
409      return new VersionMonitorEntry(entry);
410    }
411
412    return new MonitorEntry(entry);
413  }
414
415
416
417  /**
418   * Gets the most appropriate monitor class from the provided entry.
419   *
420   * @param  entry  The entry from which to extract the monitor class.
421   *
422   * @return  The most appropriate monitor class from the provided entry, or the
423   *          generic monitor object class if no appropriate subclass could be
424   *          identified.
425   */
426  private static String getMonitorClass(final Entry entry)
427  {
428    String monitorOC = null;
429    final String[] ocNames = entry.getObjectClassValues();
430    for (final String oc : ocNames)
431    {
432      if (oc.equalsIgnoreCase("top") ||
433          oc.equalsIgnoreCase("extensibleObject") ||
434          oc.equalsIgnoreCase(GENERIC_MONITOR_OC))
435      {
436        // This isn't the class we're looking for.
437        continue;
438      }
439      else if (oc.equalsIgnoreCase(
440                    NumericGaugeMonitorEntry.NUMERIC_GAUGE_MONITOR_OC) ||
441               oc.equalsIgnoreCase(
442                    IndicatorGaugeMonitorEntry.INDICATOR_GAUGE_MONITOR_OC))
443      {
444        // These classes are subclasses of the base gauge monitor class.
445        // We'll allow them even if the monitor class is already set.
446        monitorOC = oc;
447      }
448      else if (oc.equalsIgnoreCase(GaugeMonitorEntry.GAUGE_MONITOR_OC))
449      {
450        // This is a superclass for the numeric and indicator gauge classes.
451        // We'll use it only if the monitor class isn't set, but we won't
452        // complain if the monitor class is already set.
453        if (monitorOC == null)
454        {
455          monitorOC = oc;
456        }
457      }
458      else
459      {
460        if (monitorOC != null)
461        {
462          if (Debug.debugEnabled(DebugType.MONITOR))
463          {
464            Debug.debugMonitor(entry,
465                 "Multiple monitor subclasses detected:  " + monitorOC +
466                      " and " + oc);
467          }
468        }
469
470        monitorOC = oc;
471      }
472    }
473
474    if (monitorOC == null)
475    {
476      if (entry.hasObjectClass(GENERIC_MONITOR_OC))
477      {
478        Debug.debugMonitor(entry, "No appropriate monitor subclass");
479      }
480      else
481      {
482        Debug.debugMonitor(entry, "Missing the generic monitor class");
483      }
484
485      return GENERIC_MONITOR_OC;
486    }
487    else
488    {
489      return monitorOC;
490    }
491  }
492
493
494
495  /**
496   * Retrieves the value of the specified attribute as a {@code Boolean} object.
497   *
498   * @param  attributeName  The name of the target attribute.
499   *
500   * @return  The {@code Boolean} object parsed from the specified attribute, or
501   *          {@code null} if the attribute does not exist in the entry or it
502   *          cannot be parsed as a {@code Boolean} value.
503   */
504  protected final Boolean getBoolean(final String attributeName)
505  {
506    final String valueStr = entry.getAttributeValue(attributeName);
507    if (valueStr == null)
508    {
509      if (Debug.debugEnabled(DebugType.MONITOR))
510      {
511        Debug.debugMonitor(entry, "No value for Boolean attribute " +
512             attributeName);
513      }
514
515      return null;
516    }
517    else if (valueStr.equalsIgnoreCase("true"))
518    {
519      return Boolean.TRUE;
520    }
521    else if (valueStr.equalsIgnoreCase("false"))
522    {
523      return Boolean.FALSE;
524    }
525    else
526    {
527      if (Debug.debugEnabled(DebugType.MONITOR))
528      {
529        Debug.debugMonitor(entry,
530             "Invalid value '" + valueStr + "' for Boolean attribute " +
531                  attributeName);
532      }
533
534      return null;
535    }
536  }
537
538
539
540  /**
541   * Retrieves the value of the specified attribute as a {@code Date} object.
542   *
543   * @param  attributeName  The name of the target attribute.
544   *
545   * @return  The {@code Date} object parsed from the specified attribute, or
546   *          {@code null} if the attribute does not exist in the entry or it
547   *          cannot be parsed as a {@code Date} value.
548   */
549  protected final Date getDate(final String attributeName)
550  {
551    final String valueStr = entry.getAttributeValue(attributeName);
552    if (valueStr == null)
553    {
554      if (Debug.debugEnabled(DebugType.MONITOR))
555      {
556        Debug.debugMonitor(entry, "No value for Date attribute " +
557             attributeName);
558      }
559
560      return null;
561    }
562    else
563    {
564      try
565      {
566        return StaticUtils.decodeGeneralizedTime(valueStr);
567      }
568      catch (final Exception e)
569      {
570        Debug.debugException(e);
571
572        if (Debug.debugEnabled(DebugType.MONITOR))
573        {
574          Debug.debugMonitor(entry,
575               "Invalid value '" + valueStr + "' for Date attribute " +
576                    attributeName);
577        }
578
579        return null;
580      }
581    }
582  }
583
584
585
586  /**
587   * Retrieves the value of the specified attribute as a {@code Double} object.
588   *
589   * @param  attributeName  The name of the target attribute.
590   *
591   * @return  The {@code Double} object parsed from the specified attribute, or
592   *          {@code null} if the attribute does not exist in the entry or it
593   *          cannot be parsed as a {@code Double} value.
594   */
595  protected final Double getDouble(final String attributeName)
596  {
597    final String valueStr = entry.getAttributeValue(attributeName);
598    if (valueStr == null)
599    {
600      if (Debug.debugEnabled(DebugType.MONITOR))
601      {
602        Debug.debugMonitor(entry, "No value for Double attribute " +
603             attributeName);
604      }
605
606      return null;
607    }
608    else
609    {
610      try
611      {
612        return Double.parseDouble(valueStr);
613      }
614      catch (final Exception e)
615      {
616        Debug.debugException(e);
617
618        if (Debug.debugEnabled(DebugType.MONITOR))
619        {
620          Debug.debugMonitor(entry,
621               "Invalid value '" + valueStr + "' for Double attribute " +
622                    attributeName);
623        }
624
625        return null;
626      }
627    }
628  }
629
630
631
632  /**
633   * Retrieves the value of the specified attribute as an {@code Integer}
634   * object.
635   *
636   * @param  attributeName  The name of the target attribute.
637   *
638   * @return  The {@code Integer} object parsed from the specified attribute, or
639   *          {@code null} if the attribute does not exist in the entry or it
640   *          cannot be parsed as an {@code Integer} value.
641   */
642  protected final Integer getInteger(final String attributeName)
643  {
644    final String valueStr = entry.getAttributeValue(attributeName);
645    if (valueStr == null)
646    {
647      if (Debug.debugEnabled(DebugType.MONITOR))
648      {
649        Debug.debugMonitor(entry, "No value for Integer attribute " +
650             attributeName);
651      }
652
653      return null;
654    }
655    else
656    {
657      try
658      {
659        return Integer.parseInt(valueStr);
660      }
661      catch (final Exception e)
662      {
663        Debug.debugException(e);
664
665        if (Debug.debugEnabled(DebugType.MONITOR))
666        {
667          Debug.debugMonitor(entry,
668               "Invalid value '" + valueStr + "' for Integer attribute " +
669                    attributeName);
670        }
671
672        return null;
673      }
674    }
675  }
676
677
678
679  /**
680   * Retrieves the value of the specified attribute as a {@code Long} object.
681   *
682   * @param  attributeName  The name of the target attribute.
683   *
684   * @return  The {@code Long} object parsed from the specified attribute, or
685   *          {@code null} if the attribute does not exist in the entry or it
686   *          cannot be parsed as a {@code Long} value.
687   */
688  protected final Long getLong(final String attributeName)
689  {
690    final String valueStr = entry.getAttributeValue(attributeName);
691    if (valueStr == null)
692    {
693      if (Debug.debugEnabled(DebugType.MONITOR))
694      {
695        Debug.debugMonitor(entry,
696             "No value for Long attribute " + attributeName);
697      }
698
699      return null;
700    }
701    else
702    {
703      try
704      {
705        return Long.parseLong(valueStr);
706      }
707      catch (final Exception e)
708      {
709        Debug.debugException(e);
710
711        if (Debug.debugEnabled(DebugType.MONITOR))
712        {
713          Debug.debugMonitor(entry,
714               "Invalid value '" + valueStr + "' for Long attribute " +
715                    attributeName);
716        }
717
718        return null;
719      }
720    }
721  }
722
723
724
725  /**
726   * Retrieves the value of the specified attribute as a string.
727   *
728   * @param  attributeName  The name of the target attribute.
729   *
730   * @return  The string value of the specified attribute, or {@code null} if it
731   *          does not exist in the entry.
732   */
733  protected final String getString(final String attributeName)
734  {
735    final String valueStr = entry.getAttributeValue(attributeName);
736    if ((valueStr == null) && Debug.debugEnabled(DebugType.MONITOR))
737    {
738      Debug.debugMonitor(entry,
739           "No value for string attribute " + attributeName);
740    }
741
742    return valueStr;
743  }
744
745
746
747  /**
748   * Retrieves the set of values of the specified attribute as a string list.
749   *
750   * @param  attributeName  The name of the target attribute.
751   *
752   * @return  The string values of the specified attribute, or an empty list if
753   *          the specified attribute does not exist in the entry.
754   */
755  protected final List<String> getStrings(final String attributeName)
756  {
757    final String[] valueStrs = entry.getAttributeValues(attributeName);
758    if (valueStrs == null)
759    {
760      if (Debug.debugEnabled(DebugType.MONITOR))
761      {
762        Debug.debugMonitor(entry,
763             "No values for string attribute " + attributeName);
764      }
765
766      return Collections.emptyList();
767    }
768
769    return Collections.unmodifiableList(Arrays.asList(valueStrs));
770  }
771
772
773
774  /**
775   * Adds a new monitor attribute to the specified map using the provided
776   * information.
777   *
778   * @param  attrs        The attribute map to which the information should be
779   *                      added.
780   * @param  name         The name to use for this monitor attribute.  It must
781   *                      be unique among all other monitor attribute names for
782   *                      the associated monitor entry.
783   * @param  displayName  The human-readable display name for the monitor
784   *                      attribute.
785   * @param  description  The human-readable description for the monitor
786   *                      attribute.
787   * @param  value        The value for the monitor attribute.
788   */
789  protected static void addMonitorAttribute(
790                             final Map<String,MonitorAttribute> attrs,
791                             final String name, final String displayName,
792                             final String description, final Boolean value)
793  {
794    final String lowerName = StaticUtils.toLowerCase(name);
795
796    final MonitorAttribute a =
797         new MonitorAttribute(lowerName, displayName, description, value);
798    attrs.put(lowerName, a);
799  }
800
801
802
803  /**
804   * Adds a new monitor attribute to the specified map using the provided
805   * information.
806   *
807   * @param  attrs        The attribute map to which the information should be
808   *                      added.
809   * @param  name         The name to use for this monitor attribute.  It must
810   *                      be unique among all other monitor attribute names for
811   *                      the associated monitor entry.
812   * @param  displayName  The human-readable display name for the monitor
813   *                      attribute.
814   * @param  description  The human-readable description for the monitor
815   *                      attribute.
816   * @param  value        The value for the monitor attribute.
817   */
818  protected static void addMonitorAttribute(
819                             final Map<String,MonitorAttribute> attrs,
820                             final String name, final String displayName,
821                             final String description, final Date value)
822  {
823    final String lowerName = StaticUtils.toLowerCase(name);
824
825    final MonitorAttribute a =
826         new MonitorAttribute(lowerName, displayName, description, value);
827    attrs.put(lowerName, a);
828  }
829
830
831
832  /**
833   * Adds a new monitor attribute to the specified map using the provided
834   * information.
835   *
836   * @param  attrs        The attribute map to which the information should be
837   *                      added.
838   * @param  name         The name to use for this monitor attribute.  It must
839   *                      be unique among all other monitor attribute names for
840   *                      the associated monitor entry.
841   * @param  displayName  The human-readable display name for the monitor
842   *                      attribute.
843   * @param  description  The human-readable description for the monitor
844   *                      attribute.
845   * @param  value        The value for the monitor attribute.
846   */
847  protected static void addMonitorAttribute(
848                             final Map<String,MonitorAttribute> attrs,
849                             final String name, final String displayName,
850                             final String description, final Double value)
851  {
852    final String lowerName = StaticUtils.toLowerCase(name);
853
854    final MonitorAttribute a =
855         new MonitorAttribute(lowerName, displayName, description, value);
856    attrs.put(lowerName, a);
857  }
858
859
860
861  /**
862   * Adds a new monitor attribute to the specified map using the provided
863   * information.
864   *
865   * @param  attrs        The attribute map to which the information should be
866   *                      added.
867   * @param  name         The name to use for this monitor attribute.  It must
868   *                      be unique among all other monitor attribute names for
869   *                      the associated monitor entry.
870   * @param  displayName  The human-readable display name for the monitor
871   *                      attribute.
872   * @param  description  The human-readable description for the monitor
873   *                      attribute.
874   * @param  value        The value for the monitor attribute.
875   */
876  protected static void addMonitorAttribute(
877                             final Map<String,MonitorAttribute> attrs,
878                             final String name, final String displayName,
879                             final String description, final Integer value)
880  {
881    final String lowerName = StaticUtils.toLowerCase(name);
882
883    final MonitorAttribute a =
884         new MonitorAttribute(lowerName, displayName, description, value);
885    attrs.put(lowerName, a);
886  }
887
888
889
890  /**
891   * Adds a new monitor attribute to the specified map using the provided
892   * information.
893   *
894   * @param  attrs        The attribute map to which the information should be
895   *                      added.
896   * @param  name         The name to use for this monitor attribute.  It must
897   *                      be unique among all other monitor attribute names for
898   *                      the associated monitor entry.
899   * @param  displayName  The human-readable display name for the monitor
900   *                      attribute.
901   * @param  description  The human-readable description for the monitor
902   *                      attribute.
903   * @param  value        The value for the monitor attribute.
904   */
905  protected static void addMonitorAttribute(
906                             final Map<String,MonitorAttribute> attrs,
907                             final String name, final String displayName,
908                             final String description, final Long value)
909  {
910    final String lowerName = StaticUtils.toLowerCase(name);
911
912    final MonitorAttribute a =
913         new MonitorAttribute(lowerName, displayName, description, value);
914    attrs.put(lowerName, a);
915  }
916
917
918
919  /**
920   * Adds a new monitor attribute to the specified map using the provided
921   * information.
922   *
923   * @param  attrs        The attribute map to which the information should be
924   *                      added.
925   * @param  name         The name to use for this monitor attribute.  It must
926   *                      be unique among all other monitor attribute names for
927   *                      the associated monitor entry.
928   * @param  displayName  The human-readable display name for the monitor
929   *                      attribute.
930   * @param  description  The human-readable description for the monitor
931   *                      attribute.
932   * @param  value        The value for the monitor attribute.
933   */
934  protected static void addMonitorAttribute(
935                             final Map<String,MonitorAttribute> attrs,
936                             final String name, final String displayName,
937                             final String description, final String value)
938  {
939    final String lowerName = StaticUtils.toLowerCase(name);
940
941    final MonitorAttribute a =
942         new MonitorAttribute(lowerName, displayName, description, value);
943    attrs.put(lowerName, a);
944  }
945
946
947
948  /**
949   * Adds a new monitor attribute to the specified map using the provided
950   * information.
951   *
952   * @param  attrs        The attribute map to which the information should be
953   *                      added.
954   * @param  name         The name to use for this monitor attribute.  It must
955   *                      be unique among all other monitor attribute names for
956   *                      the associated monitor entry.
957   * @param  displayName  The human-readable display name for the monitor
958   *                      attribute.
959   * @param  description  The human-readable description for the monitor
960   *                      attribute.
961   * @param  values       The set of values for the monitor attribute.
962   */
963  protected static void addMonitorAttribute(
964                             final Map<String,MonitorAttribute> attrs,
965                             final String name, final String displayName,
966                             final String description,
967                             final List<String> values)
968  {
969    final String lowerName = StaticUtils.toLowerCase(name);
970
971    final MonitorAttribute a =
972         new MonitorAttribute(lowerName, displayName, description,
973                              values.toArray(new String[values.size()]));
974    attrs.put(lowerName, a);
975  }
976
977
978
979  /**
980   * Retrieves a string representation of this monitor entry.
981   *
982   * @return  A string representation of this monitor entry.
983   */
984  @Override()
985  public final String toString()
986  {
987    final StringBuilder buffer = new StringBuilder();
988    toString(buffer);
989    return buffer.toString();
990  }
991
992
993
994  /**
995   * Appends a string representation of this monitor entry to the provided
996   * buffer.
997   *
998   * @param  buffer  The buffer to which the information should be appended.
999   */
1000  public final void toString(final StringBuilder buffer)
1001  {
1002    buffer.append("MonitorEntry(dn='");
1003    buffer.append(entry.getDN());
1004    buffer.append("', monitorClass='");
1005    buffer.append(monitorClass);
1006    buffer.append('\'');
1007
1008    final Iterator<MonitorAttribute> iterator =
1009         getMonitorAttributes().values().iterator();
1010    while (iterator.hasNext())
1011    {
1012      buffer.append(iterator.next());
1013      if (iterator.hasNext())
1014      {
1015        buffer.append(", ");
1016      }
1017    }
1018
1019    buffer.append(')');
1020  }
1021}