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