001/*
002 * Copyright 2008-2018 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2018 Ping Identity Corporation
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.ldap.sdk.unboundidds.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.DebugType;
038import com.unboundid.util.NotExtensible;
039import com.unboundid.util.ThreadSafety;
040import com.unboundid.util.ThreadSafetyLevel;
041
042import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*;
043import static com.unboundid.util.Debug.*;
044import static com.unboundid.util.StaticUtils.*;
045import static com.unboundid.util.Validator.*;
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 Alcatel-Lucent 8661
052 * server instance.  Subclasses may provide specific methods for interpreting
053 * 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 Alcatel-Lucent 8661
059 *   server products.  These classes provide support for proprietary
060 *   functionality or for external specifications that are not considered stable
061 *   or mature enough to be guaranteed to work in an interoperable way with
062 *   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    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<String,MonitorAttribute>();
221
222    for (final Attribute a : entry.getAttributes())
223    {
224      final String lowerName = 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 (debugEnabled(DebugType.MONITOR))
463          {
464            debugMonitor(entry,
465                         "Multiple monitor subclasses detected:  " +
466                              monitorOC + " 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        debugMonitor(entry, "No appropriate monitor subclass");
479      }
480      else
481      {
482        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 (debugEnabled(DebugType.MONITOR))
510      {
511        debugMonitor(entry, "No value for Boolean attribute " + attributeName);
512      }
513
514      return null;
515    }
516    else if (valueStr.equalsIgnoreCase("true"))
517    {
518      return Boolean.TRUE;
519    }
520    else if (valueStr.equalsIgnoreCase("false"))
521    {
522      return Boolean.FALSE;
523    }
524    else
525    {
526      if (debugEnabled(DebugType.MONITOR))
527      {
528        debugMonitor(entry,
529                     "Invalid value '" + valueStr + "' for Boolean attribute " +
530                          attributeName);
531      }
532
533      return null;
534    }
535  }
536
537
538
539  /**
540   * Retrieves the value of the specified attribute as a {@code Date} object.
541   *
542   * @param  attributeName  The name of the target attribute.
543   *
544   * @return  The {@code Date} object parsed from the specified attribute, or
545   *          {@code null} if the attribute does not exist in the entry or it
546   *          cannot be parsed as a {@code Date} value.
547   */
548  protected final Date getDate(final String attributeName)
549  {
550    final String valueStr = entry.getAttributeValue(attributeName);
551    if (valueStr == null)
552    {
553      if (debugEnabled(DebugType.MONITOR))
554      {
555        debugMonitor(entry, "No value for Date attribute " + attributeName);
556      }
557
558      return null;
559    }
560    else
561    {
562      try
563      {
564        return decodeGeneralizedTime(valueStr);
565      }
566      catch (final Exception e)
567      {
568        debugException(e);
569
570        if (debugEnabled(DebugType.MONITOR))
571        {
572          debugMonitor(entry,
573                       "Invalid value '" + valueStr + "' for Date attribute " +
574                            attributeName);
575        }
576
577        return null;
578      }
579    }
580  }
581
582
583
584  /**
585   * Retrieves the value of the specified attribute as a {@code Double} object.
586   *
587   * @param  attributeName  The name of the target attribute.
588   *
589   * @return  The {@code Double} object parsed from the specified attribute, or
590   *          {@code null} if the attribute does not exist in the entry or it
591   *          cannot be parsed as a {@code Double} value.
592   */
593  protected final Double getDouble(final String attributeName)
594  {
595    final String valueStr = entry.getAttributeValue(attributeName);
596    if (valueStr == null)
597    {
598      if (debugEnabled(DebugType.MONITOR))
599      {
600        debugMonitor(entry, "No value for Double attribute " + attributeName);
601      }
602
603      return null;
604    }
605    else
606    {
607      try
608      {
609        return Double.parseDouble(valueStr);
610      }
611      catch (final Exception e)
612      {
613        debugException(e);
614
615        if (debugEnabled(DebugType.MONITOR))
616        {
617          debugMonitor(entry,
618                       "Invalid value '" + valueStr +
619                            "' for Double attribute " + attributeName);
620        }
621
622        return null;
623      }
624    }
625  }
626
627
628
629  /**
630   * Retrieves the value of the specified attribute as an {@code Integer}
631   * object.
632   *
633   * @param  attributeName  The name of the target attribute.
634   *
635   * @return  The {@code Integer} object parsed from the specified attribute, or
636   *          {@code null} if the attribute does not exist in the entry or it
637   *          cannot be parsed as an {@code Integer} value.
638   */
639  protected final Integer getInteger(final String attributeName)
640  {
641    final String valueStr = entry.getAttributeValue(attributeName);
642    if (valueStr == null)
643    {
644      if (debugEnabled(DebugType.MONITOR))
645      {
646        debugMonitor(entry, "No value for Integer attribute " + attributeName);
647      }
648
649      return null;
650    }
651    else
652    {
653      try
654      {
655        return Integer.parseInt(valueStr);
656      }
657      catch (final Exception e)
658      {
659        debugException(e);
660
661        if (debugEnabled(DebugType.MONITOR))
662        {
663          debugMonitor(entry,
664               "Invalid value '" + valueStr + "' for Integer attribute " +
665                    attributeName);
666        }
667
668        return null;
669      }
670    }
671  }
672
673
674
675  /**
676   * Retrieves the value of the specified attribute as a {@code Long} object.
677   *
678   * @param  attributeName  The name of the target attribute.
679   *
680   * @return  The {@code Long} object parsed from the specified attribute, or
681   *          {@code null} if the attribute does not exist in the entry or it
682   *          cannot be parsed as a {@code Long} value.
683   */
684  protected final Long getLong(final String attributeName)
685  {
686    final String valueStr = entry.getAttributeValue(attributeName);
687    if (valueStr == null)
688    {
689      if (debugEnabled(DebugType.MONITOR))
690      {
691        debugMonitor(entry, "No value for Long attribute " + attributeName);
692      }
693
694      return null;
695    }
696    else
697    {
698      try
699      {
700        return Long.parseLong(valueStr);
701      }
702      catch (final Exception e)
703      {
704        debugException(e);
705
706        if (debugEnabled(DebugType.MONITOR))
707        {
708          debugMonitor(entry,
709                       "Invalid value '" + valueStr + "' for Long attribute " +
710                            attributeName);
711        }
712
713        return null;
714      }
715    }
716  }
717
718
719
720  /**
721   * Retrieves the value of the specified attribute as a string.
722   *
723   * @param  attributeName  The name of the target attribute.
724   *
725   * @return  The string value of the specified attribute, or {@code null} if it
726   *          does not exist in the entry.
727   */
728  protected final String getString(final String attributeName)
729  {
730    final String valueStr = entry.getAttributeValue(attributeName);
731    if ((valueStr == null) && debugEnabled(DebugType.MONITOR))
732    {
733      debugMonitor(entry, "No value for string attribute " + attributeName);
734    }
735
736    return valueStr;
737  }
738
739
740
741  /**
742   * Retrieves the set of values of the specified attribute as a string list.
743   *
744   * @param  attributeName  The name of the target attribute.
745   *
746   * @return  The string values of the specified attribute, or an empty list if
747   *          the specified attribute does not exist in the entry.
748   */
749  protected final List<String> getStrings(final String attributeName)
750  {
751    final String[] valueStrs = entry.getAttributeValues(attributeName);
752    if (valueStrs == null)
753    {
754      if (debugEnabled(DebugType.MONITOR))
755      {
756        debugMonitor(entry, "No values for string attribute " + attributeName);
757      }
758
759      return Collections.emptyList();
760    }
761
762    return Collections.unmodifiableList(Arrays.asList(valueStrs));
763  }
764
765
766
767  /**
768   * Adds a new monitor attribute to the specified map using the provided
769   * information.
770   *
771   * @param  attrs        The attribute map to which the information should be
772   *                      added.
773   * @param  name         The name to use for this monitor attribute.  It must
774   *                      be unique among all other monitor attribute names for
775   *                      the associated monitor entry.
776   * @param  displayName  The human-readable display name for the monitor
777   *                      attribute.
778   * @param  description  The human-readable description for the monitor
779   *                      attribute.
780   * @param  value        The value for the monitor attribute.
781   */
782  protected static void addMonitorAttribute(
783                             final Map<String,MonitorAttribute> attrs,
784                             final String name, final String displayName,
785                             final String description, final Boolean value)
786  {
787    final String lowerName = toLowerCase(name);
788
789    final MonitorAttribute a =
790         new MonitorAttribute(lowerName, displayName, description, value);
791    attrs.put(lowerName, a);
792  }
793
794
795
796  /**
797   * Adds a new monitor attribute to the specified map using the provided
798   * information.
799   *
800   * @param  attrs        The attribute map to which the information should be
801   *                      added.
802   * @param  name         The name to use for this monitor attribute.  It must
803   *                      be unique among all other monitor attribute names for
804   *                      the associated monitor entry.
805   * @param  displayName  The human-readable display name for the monitor
806   *                      attribute.
807   * @param  description  The human-readable description for the monitor
808   *                      attribute.
809   * @param  value        The value for the monitor attribute.
810   */
811  protected static void addMonitorAttribute(
812                             final Map<String,MonitorAttribute> attrs,
813                             final String name, final String displayName,
814                             final String description, final Date value)
815  {
816    final String lowerName = toLowerCase(name);
817
818    final MonitorAttribute a =
819         new MonitorAttribute(lowerName, displayName, description, value);
820    attrs.put(lowerName, a);
821  }
822
823
824
825  /**
826   * Adds a new monitor attribute to the specified map using the provided
827   * information.
828   *
829   * @param  attrs        The attribute map to which the information should be
830   *                      added.
831   * @param  name         The name to use for this monitor attribute.  It must
832   *                      be unique among all other monitor attribute names for
833   *                      the associated monitor entry.
834   * @param  displayName  The human-readable display name for the monitor
835   *                      attribute.
836   * @param  description  The human-readable description for the monitor
837   *                      attribute.
838   * @param  value        The value for the monitor attribute.
839   */
840  protected static void addMonitorAttribute(
841                             final Map<String,MonitorAttribute> attrs,
842                             final String name, final String displayName,
843                             final String description, final Double value)
844  {
845    final String lowerName = toLowerCase(name);
846
847    final MonitorAttribute a =
848         new MonitorAttribute(lowerName, displayName, description, value);
849    attrs.put(lowerName, a);
850  }
851
852
853
854  /**
855   * Adds a new monitor attribute to the specified map using the provided
856   * information.
857   *
858   * @param  attrs        The attribute map to which the information should be
859   *                      added.
860   * @param  name         The name to use for this monitor attribute.  It must
861   *                      be unique among all other monitor attribute names for
862   *                      the associated monitor entry.
863   * @param  displayName  The human-readable display name for the monitor
864   *                      attribute.
865   * @param  description  The human-readable description for the monitor
866   *                      attribute.
867   * @param  value        The value for the monitor attribute.
868   */
869  protected static void addMonitorAttribute(
870                             final Map<String,MonitorAttribute> attrs,
871                             final String name, final String displayName,
872                             final String description, final Integer value)
873  {
874    final String lowerName = toLowerCase(name);
875
876    final MonitorAttribute a =
877         new MonitorAttribute(lowerName, displayName, description, value);
878    attrs.put(lowerName, a);
879  }
880
881
882
883  /**
884   * Adds a new monitor attribute to the specified map using the provided
885   * information.
886   *
887   * @param  attrs        The attribute map to which the information should be
888   *                      added.
889   * @param  name         The name to use for this monitor attribute.  It must
890   *                      be unique among all other monitor attribute names for
891   *                      the associated monitor entry.
892   * @param  displayName  The human-readable display name for the monitor
893   *                      attribute.
894   * @param  description  The human-readable description for the monitor
895   *                      attribute.
896   * @param  value        The value for the monitor attribute.
897   */
898  protected static void addMonitorAttribute(
899                             final Map<String,MonitorAttribute> attrs,
900                             final String name, final String displayName,
901                             final String description, final Long value)
902  {
903    final String lowerName = toLowerCase(name);
904
905    final MonitorAttribute a =
906         new MonitorAttribute(lowerName, displayName, description, value);
907    attrs.put(lowerName, a);
908  }
909
910
911
912  /**
913   * Adds a new monitor attribute to the specified map using the provided
914   * information.
915   *
916   * @param  attrs        The attribute map to which the information should be
917   *                      added.
918   * @param  name         The name to use for this monitor attribute.  It must
919   *                      be unique among all other monitor attribute names for
920   *                      the associated monitor entry.
921   * @param  displayName  The human-readable display name for the monitor
922   *                      attribute.
923   * @param  description  The human-readable description for the monitor
924   *                      attribute.
925   * @param  value        The value for the monitor attribute.
926   */
927  protected static void addMonitorAttribute(
928                             final Map<String,MonitorAttribute> attrs,
929                             final String name, final String displayName,
930                             final String description, final String value)
931  {
932    final String lowerName = toLowerCase(name);
933
934    final MonitorAttribute a =
935         new MonitorAttribute(lowerName, displayName, description, value);
936    attrs.put(lowerName, a);
937  }
938
939
940
941  /**
942   * Adds a new monitor attribute to the specified map using the provided
943   * information.
944   *
945   * @param  attrs        The attribute map to which the information should be
946   *                      added.
947   * @param  name         The name to use for this monitor attribute.  It must
948   *                      be unique among all other monitor attribute names for
949   *                      the associated monitor entry.
950   * @param  displayName  The human-readable display name for the monitor
951   *                      attribute.
952   * @param  description  The human-readable description for the monitor
953   *                      attribute.
954   * @param  values       The set of values for the monitor attribute.
955   */
956  protected static void addMonitorAttribute(
957                             final Map<String,MonitorAttribute> attrs,
958                             final String name, final String displayName,
959                             final String description,
960                             final List<String> values)
961  {
962    final String lowerName = toLowerCase(name);
963
964    final MonitorAttribute a =
965         new MonitorAttribute(lowerName, displayName, description,
966                              values.toArray(new String[values.size()]));
967    attrs.put(lowerName, a);
968  }
969
970
971
972  /**
973   * Retrieves a string representation of this monitor entry.
974   *
975   * @return  A string representation of this monitor entry.
976   */
977  @Override()
978  public final String toString()
979  {
980    final StringBuilder buffer = new StringBuilder();
981    toString(buffer);
982    return buffer.toString();
983  }
984
985
986
987  /**
988   * Appends a string representation of this monitor entry to the provided
989   * buffer.
990   *
991   * @param  buffer  The buffer to which the information should be appended.
992   */
993  public final void toString(final StringBuilder buffer)
994  {
995    buffer.append("MonitorEntry(dn='");
996    buffer.append(entry.getDN());
997    buffer.append("', monitorClass='");
998    buffer.append(monitorClass);
999    buffer.append('\'');
1000
1001    final Iterator<MonitorAttribute> iterator =
1002         getMonitorAttributes().values().iterator();
1003    while (iterator.hasNext())
1004    {
1005      buffer.append(iterator.next());
1006      if (iterator.hasNext())
1007      {
1008        buffer.append(", ");
1009      }
1010    }
1011
1012    buffer.append(')');
1013  }
1014}