001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.config;
028    import org.opends.messages.Message;
029    
030    
031    
032    import java.util.Iterator;
033    import java.util.LinkedHashSet;
034    import java.util.List;
035    import javax.management.AttributeList;
036    import javax.management.MBeanAttributeInfo;
037    import javax.management.MBeanParameterInfo;
038    
039    import org.opends.server.api.AttributeSyntax;
040    import org.opends.server.types.Attribute;
041    import org.opends.server.types.AttributeValue;
042    
043    import static org.opends.messages.ConfigMessages.*;
044    /**
045     * This class defines a configuration attribute, which can hold zero or more
046     * values associated with a configurable property within the Directory Server.
047     * Subclasses should define and enforce actual data types.
048     */
049    @org.opends.server.types.PublicAPI(
050         stability=org.opends.server.types.StabilityLevel.VOLATILE,
051         mayInstantiate=true,
052         mayExtend=true,
053         mayInvoke=true)
054    public abstract class ConfigAttribute
055    {
056      // Indicates whether this configuration attribute has pending changes that
057      // will be applied after appropriate administrative action has been performed.
058      private boolean hasPendingValues;
059    
060      // Indicates whether this configuration attribute may have multiple values.
061      private boolean isMultiValued;
062    
063      // Indicates whether this configuration attribute is required to have a value.
064      private boolean isRequired;
065    
066      // Indicates whether changes to this attribute require administrative action
067      // before they will take effect.
068      private boolean requiresAdminAction;
069    
070      // The value or set of values that are currently in effect for this
071      // configuration attribute.
072      private LinkedHashSet<AttributeValue> activeValues;
073    
074      // The value or set of values that will be in effect once the appropriate
075      // administrative action has been taken.
076      private LinkedHashSet<AttributeValue> pendingValues;
077    
078      // The description for this configuration attribute.
079      private Message description;
080    
081      // The name for this configuration attribute.
082      private String name;
083    
084    
085    
086      /**
087       * Creates a new configuration attribute stub with the provided information
088       * but no values.  The values will be set using the
089       * <CODE>setInitialValue</CODE> method.
090       *
091       * @param  name                 The name for this configuration attribute.
092       * @param  description          The description for this configuration
093       *                              attribute.
094       * @param  isRequired           Indicates whether this configuration attribute
095       *                              is required to have at least one value.
096       * @param  isMultiValued        Indicates whether this configuration attribute
097       *                              may have multiple values.
098       * @param  requiresAdminAction  Indicates whether changes to this
099       *                              configuration attribute require administrative
100       *                              action before they will take effect.
101       */
102      protected ConfigAttribute(String name, Message description,
103                                boolean isRequired, boolean isMultiValued,
104                                boolean requiresAdminAction)
105      {
106        this.name                = name;
107        this.description         = description;
108        this.isRequired          = isRequired;
109        this.isMultiValued       = isMultiValued;
110        this.requiresAdminAction = requiresAdminAction;
111    
112        hasPendingValues = false;
113        activeValues     = new LinkedHashSet<AttributeValue>();
114        pendingValues    = activeValues;
115      }
116    
117    
118    
119      /**
120       * Creates a new configuration attribute with the provided information.
121       *
122       * @param  name                 The name for this configuration attribute.
123       * @param  description          The description for this configuration
124       *                              attribute.
125       * @param  isRequired           Indicates whether this configuration attribute
126       *                              is required to have at least one value.
127       * @param  isMultiValued        Indicates whether this configuration attribute
128       *                              may have multiple values.
129       * @param  requiresAdminAction  Indicates whether changes to this
130       *                              configuration attribute require administrative
131       *                              action before they will take effect.
132       * @param  activeValues         The set of values for this attribute that are
133       *                              currently active.
134       */
135      protected ConfigAttribute(String name, Message description,
136                                boolean isRequired, boolean isMultiValued,
137                                boolean requiresAdminAction,
138                                LinkedHashSet<AttributeValue> activeValues)
139      {
140        this.name                = name;
141        this.description         = description;
142        this.isRequired          = isRequired;
143        this.isMultiValued       = isMultiValued;
144        this.requiresAdminAction = requiresAdminAction;
145        this.hasPendingValues    = false;
146    
147        if (activeValues == null)
148        {
149          this.activeValues = new LinkedHashSet<AttributeValue>();
150        }
151        else
152        {
153          this.activeValues = activeValues;
154        }
155    
156        this.pendingValues = this.activeValues;
157      }
158    
159    
160    
161      /**
162       * Creates a new configuration attribute with the provided information.
163       *
164       * @param  name                 The name for this configuration attribute.
165       * @param  description          The description for this configuration
166       *                              attribute.
167       * @param  isRequired           Indicates whether this configuration attribute
168       *                              is required to have at least one value.
169       * @param  isMultiValued        Indicates whether this configuration attribute
170       *                              may have multiple values.
171       * @param  requiresAdminAction  Indicates whether changes to this
172       *                              configuration attribute require administrative
173       *                              action before they will take effect.
174       * @param  activeValues         The set of values for this attribute that are
175       *                              currently active.
176       * @param  hasPendingValues     Indicates whether this attribute has any
177       *                              pending values that will take effect after
178       *                              appropriate administrative action.
179       * @param  pendingValues        The set of values for this attribute that will
180       *                              be in effect after the appropriate
181       *                              administrative action is taken.  This may be
182       *                              <CODE>null</CODE> if changes will take effect
183       *                              immediately.
184       */
185      protected ConfigAttribute(String name, Message description,
186                                boolean isRequired, boolean isMultiValued,
187                                boolean requiresAdminAction,
188                                LinkedHashSet<AttributeValue> activeValues,
189                                boolean hasPendingValues,
190                                LinkedHashSet<AttributeValue> pendingValues)
191      {
192        this.name                = name;
193        this.description         = description;
194        this.isRequired          = isRequired;
195        this.isMultiValued       = isMultiValued;
196        this.requiresAdminAction = requiresAdminAction;
197        this.hasPendingValues    = hasPendingValues;
198    
199        if (activeValues == null)
200        {
201          this.activeValues = new LinkedHashSet<AttributeValue>();
202        }
203        else
204        {
205          this.activeValues = activeValues;
206        }
207    
208        if (! hasPendingValues)
209        {
210          this.pendingValues = this.activeValues;
211        }
212        else
213        {
214          if (pendingValues == null)
215          {
216            this.pendingValues = new LinkedHashSet<AttributeValue>();
217          }
218          else
219          {
220            this.pendingValues = pendingValues;
221          }
222        }
223      }
224    
225    
226    
227      /**
228       * Retrieves the name for this configuration attribute.
229       *
230       * @return  The name for this configuration attribute.
231       */
232      public String getName()
233      {
234        return name;
235      }
236    
237    
238    
239      /**
240       * Retrieves the description for this configuration attribute.
241       *
242       * @return  The description for this configuration attribute, or
243       *          <CODE>null</CODE> if there is no description.
244       */
245      public Message getDescription()
246      {
247        return description;
248      }
249    
250    
251    
252      /**
253       * Retrieves the name of the data type for this configuration attribute.  This
254       * is for informational purposes (e.g., inclusion in method signatures and
255       * other kinds of descriptions) and does not necessarily need to map to an
256       * actual Java type.
257       *
258       * @return  The name of the data type for this configuration attribute.
259       */
260      public abstract String getDataType();
261    
262    
263    
264      /**
265       * Retrieves the attribute syntax for this configuration attribute.
266       *
267       * @return  The attribute syntax for this configuration attribute.
268       */
269      public abstract AttributeSyntax getSyntax();
270    
271    
272    
273      /**
274       * Indicates whether this configuration attribute is required to have at least
275       * one value.
276       *
277       * @return  <CODE>true</CODE> if this configuration attribute is required to
278       *          have at least one value, or <CODE>false</CODE> if not.
279       */
280      public boolean isRequired()
281      {
282        return isRequired;
283      }
284    
285    
286    
287      /**
288       * Indicates whether this configuration attribute may have multiple values.
289       *
290       * @return  <CODE>true</CODE> if this configuration attribute may have
291       *          multiple values, or <CODE>false</CODE> if not.
292       */
293      public boolean isMultiValued()
294      {
295        return isMultiValued;
296      }
297    
298    
299    
300      /**
301       * Indicates whether changes to this configuration attribute require
302       * administrative action before they will take effect.
303       *
304       * @return  <CODE>true</CODE> if changes to this configuration attribute
305       *          require administrative action before they will take effect, or
306       *          <CODE>false</CODE> if changes will take effect immediately.
307       */
308      public boolean requiresAdminAction()
309      {
310        return requiresAdminAction;
311      }
312    
313    
314    
315      /**
316       * Retrieves the set of active values for this configuration attribute.  This
317       * must not be modified by the caller.
318       *
319       * @return  The set of active values for this configuration attribute.
320       */
321      public LinkedHashSet<AttributeValue> getActiveValues()
322      {
323        return activeValues;
324      }
325    
326    
327    
328      /**
329       * Indicates whether this attribute has been altered and that there are a set
330       * of pending values that will take effect after appropriate administrative
331       * action.
332       *
333       * @return  <CODE>true</CODE> if this attribute has pending values, or
334       *          <CODE>false</CODE> if not.
335       */
336      public boolean hasPendingValues()
337      {
338        return hasPendingValues;
339      }
340    
341    
342    
343      /**
344       * Retrieves the set of values that this configuration attribute will have on
345       * restart or after any necessary administrative action is performed.  For
346       * attributes whose changes take effect immediately, this will always be the
347       * same as the set of active values.  This must not be modified by the caller.
348       *
349       * @return  The set of values that this configuration attribute will have
350       *          after any appropriate administrative action is taken.
351       */
352      public LinkedHashSet<AttributeValue> getPendingValues()
353      {
354        if (requiresAdminAction)
355        {
356          return pendingValues;
357        }
358        else
359        {
360          return activeValues;
361        }
362      }
363    
364    
365    
366      /**
367       * Indicates whether the provided value is acceptable for use in this
368       * attribute.  If it is not acceptable, then the reason should be written into
369       * the provided buffer.
370       *
371       * @param  value         The value for which to make the determination.
372       * @param  rejectReason  A buffer into which a human-readable reason for the
373       *                       reject may be written.
374       *
375       * @return  <CODE>true</CODE> if the provided value is acceptable for use in
376       *          this attribute, or <CODE>false</CODE> if not.
377       */
378      public abstract boolean valueIsAcceptable(AttributeValue value,
379                                                StringBuilder rejectReason);
380    
381    
382    
383      /**
384       * Specifies the set of values for this configuration attribute.  Each value
385       * will be validated using the <CODE>valueIsAcceptable</CODE> method, and
386       * only a single value will be allowed unless <CODE>isMultiValued</CODE>
387       * returns <CODE>true</CODE>.  If the set of values is acceptable, then it
388       * will be set either as the active set of values if changes are to take
389       * effect immediately, or if not then it will be applied to the set of
390       * pending values.
391       *
392       * @param  values  The set of values to apply to this attribute.
393       *
394       * @throws  ConfigException  If the provided set of values is not acceptable
395       *                           for some reason.
396       */
397      protected void setValues(LinkedHashSet<AttributeValue> values)
398             throws ConfigException
399      {
400        // If no values are provided, then check to see if this is a required
401        // attribute.  If it is, then reject the change.
402        if ((values == null) || values.isEmpty())
403        {
404          if (isRequired)
405          {
406            Message message = ERR_CONFIG_ATTR_IS_REQUIRED.get(name);
407            throw new ConfigException(message);
408          }
409          else
410          {
411            if (requiresAdminAction)
412            {
413              if (values == null)
414              {
415                pendingValues = new LinkedHashSet<AttributeValue>();
416              }
417              else
418              {
419                pendingValues = values;
420              }
421    
422              hasPendingValues = true;
423            }
424            else
425            {
426              if (values == null)
427              {
428                activeValues = new LinkedHashSet<AttributeValue>();
429              }
430              else
431              {
432                activeValues = values;
433              }
434    
435              pendingValues    = activeValues;
436              hasPendingValues = false;
437            }
438    
439            return;
440          }
441        }
442    
443    
444        // We know that we have at least one value, so get it and see if it is OK.
445        Iterator<AttributeValue> iterator     = values.iterator();
446        AttributeValue           value        = iterator.next();
447        StringBuilder            rejectReason = new StringBuilder();
448    
449        if (! valueIsAcceptable(value, rejectReason))
450        {
451          Message message = ERR_CONFIG_ATTR_REJECTED_VALUE.get(
452              value.getStringValue(), name, rejectReason.toString());
453          throw new ConfigException(message);
454        }
455    
456    
457        // If this is not a multivalued attribute but there were more values
458        // provided, then reject it.
459        if ((! isMultiValued) && iterator.hasNext())
460        {
461          Message message = ERR_CONFIG_ATTR_SET_VALUES_IS_SINGLE_VALUED.get(name);
462          throw new ConfigException(message);
463        }
464    
465    
466        // Iterate through the remaining values to see if they are acceptable.
467        while (iterator.hasNext())
468        {
469          value = iterator.next();
470          if (! valueIsAcceptable(value, rejectReason))
471          {
472            Message message = ERR_CONFIG_ATTR_REJECTED_VALUE.get(
473                value.getStringValue(), name, rejectReason.toString());
474            throw new ConfigException(message);
475          }
476        }
477    
478    
479        // If we've gotten here, then everything is OK.  Make this the new active or
480        // pending value set depending on the configuration.
481        if (requiresAdminAction)
482        {
483          pendingValues    = values;
484          hasPendingValues = true;
485        }
486        else
487        {
488          activeValues     = values;
489          pendingValues    = activeValues;
490          hasPendingValues = false;
491    
492        }
493      }
494    
495    
496    
497      /**
498       * Specifies the set of active values for this configuration attribute.  No
499       * validation will be performed, and no checks will be made to determine if
500       * administrative action is required.
501       *
502       * @param  values  The set of active values for this configuration attribute.
503       */
504      protected void setActiveValues(LinkedHashSet<AttributeValue> values)
505      {
506        activeValues = values;
507      }
508    
509    
510    
511      /**
512       * Specifies the set of pending values for this configuration attribute.  No
513       * validation will be performed, and no checks will be made to determine if
514       * administrative action is required.
515       *
516       * @param  values  The set of pending values for this configuration attribute.
517       */
518      protected void setPendingValues(LinkedHashSet<AttributeValue> values)
519      {
520        pendingValues    = values;
521        hasPendingValues = true;
522      }
523    
524    
525    
526      /**
527       * Attempts to add the provided set of values to this configuration attribute.
528       * All of the appropriate validity checks will be performed, and the changes
529       * will be applied to either the active or pending values, depending on the
530       * configuration of this attribute.
531       *
532       * @param  values  The set of values to add to this configuration attribute.
533       *
534       * @throws  ConfigException  If a problem occurs while attempting to add the
535       *                           provided set of values to this configuration
536       *                           attribute.
537       */
538      protected void addValues(List<AttributeValue> values)
539             throws ConfigException
540      {
541        // If there are no values provided, then do nothing.
542        if (values == null)
543        {
544          return;
545        }
546    
547        int numValues = values.size();
548        if (numValues == 0)
549        {
550          return;
551        }
552    
553    
554        // Make sure that the value limit will not be exceeded for a single-valued
555        // attribute.
556        if (! isMultiValued)
557        {
558          if ((numValues > 1) || (hasPendingValues && (pendingValues.size() > 0)) ||
559              ((! hasPendingValues) && (activeValues.size() > 0)))
560          {
561            Message message = ERR_CONFIG_ATTR_ADD_VALUES_IS_SINGLE_VALUED.get(name);
562            throw new ConfigException(message);
563          }
564        }
565    
566    
567        // Create a temporary set of values that we will use for this change.  It
568        // may not actually be applied if an error occurs for some reason.
569        LinkedHashSet<AttributeValue> tempValues;
570        if (requiresAdminAction && hasPendingValues)
571        {
572          tempValues =
573               new LinkedHashSet<AttributeValue>(pendingValues.size() + numValues);
574          tempValues.addAll(pendingValues);
575        }
576        else
577        {
578          tempValues =
579               new LinkedHashSet<AttributeValue>(activeValues.size() + numValues);
580          tempValues.addAll(activeValues);
581        }
582    
583    
584        // Iterate through all of the provided values.  Make sure that each is
585        // acceptable for use and that it is not already contained in the value set.
586        StringBuilder rejectReason = new StringBuilder();
587        for (AttributeValue value : values)
588        {
589          if (tempValues.contains(value))
590          {
591            Message message = ERR_CONFIG_ATTR_ADD_VALUES_ALREADY_EXISTS.get(
592                name, value.getStringValue());
593            throw new ConfigException(message);
594          }
595    
596          if (! valueIsAcceptable(value, rejectReason))
597          {
598            Message message = ERR_CONFIG_ATTR_REJECTED_VALUE.get(
599                value.getStringValue(), name, rejectReason.toString());
600            throw new ConfigException(message);
601          }
602        }
603    
604    
605        // If we have gotten here, then everything is OK, so go ahead and assign
606        // the temporary value set to either the active or pending lists.
607        if (requiresAdminAction)
608        {
609          pendingValues    = tempValues;
610          hasPendingValues = true;
611        }
612        else
613        {
614          activeValues     = tempValues;
615          pendingValues    = tempValues;
616          hasPendingValues = false;
617        }
618      }
619    
620    
621    
622      /**
623       * Attempts to remove the set of values from this configuration attribute.
624       *
625       * @param  values  The set of values to remove from this configuration
626       *                 attribute.
627       *
628       * @throws  ConfigException  If any of the provided values are not in the
629       *                           value set, or if this is a required attribute and
630       *                           the resulting value list would be empty.
631       */
632      protected void removeValues(List<AttributeValue> values)
633             throws ConfigException
634      {
635        // Create a temporary set of values that we will use for this change.  It
636        // may not actually be applied if an error occurs for some reason.
637        LinkedHashSet<AttributeValue> tempValues;
638        if (requiresAdminAction && hasPendingValues)
639        {
640          tempValues =
641               new LinkedHashSet<AttributeValue>(pendingValues.size());
642          tempValues.addAll(pendingValues);
643        }
644        else
645        {
646          tempValues =
647               new LinkedHashSet<AttributeValue>(activeValues.size());
648          tempValues.addAll(activeValues);
649        }
650    
651    
652        // Iterate through all the provided values and make sure that they are
653        // contained in the list.  If not, then throw an exception.  If so, then
654        // remove it.
655        for (AttributeValue value : values)
656        {
657          if (! tempValues.remove(value))
658          {
659            Message message =
660                ERR_CONFIG_ATTR_NO_SUCH_VALUE.get(name, value.getStringValue());
661            throw new ConfigException(message);
662          }
663        }
664    
665    
666        // If this is a required attribute, then make sure that it will have at
667        // least one value.
668        if (isRequired && tempValues.isEmpty())
669        {
670          Message message = ERR_CONFIG_ATTR_IS_REQUIRED.get(name);
671          throw new ConfigException(message);
672        }
673    
674    
675        // If we have gotten here, then everything is OK, so go ahead and assign
676        // the temporary value set to either the active or pending lists.
677        if (requiresAdminAction)
678        {
679          pendingValues    = tempValues;
680          hasPendingValues = true;
681        }
682        else
683        {
684          activeValues     = tempValues;
685          pendingValues    = tempValues;
686          hasPendingValues = false;
687        }
688      }
689    
690    
691    
692      /**
693       * Removes all values from this configuration attribute.
694       *
695       * @throws  ConfigException  If this is a required attribute that must have at
696       *                           least one value.
697       */
698      protected void removeAllValues()
699             throws ConfigException
700      {
701        if (isRequired)
702        {
703          Message message = ERR_CONFIG_ATTR_IS_REQUIRED.get(name);
704          throw new ConfigException(message);
705        }
706    
707    
708        if (requiresAdminAction)
709        {
710          if (pendingValues == null)
711          {
712            pendingValues = new LinkedHashSet<AttributeValue>();
713          }
714          else
715          {
716            pendingValues.clear();
717          }
718    
719          hasPendingValues = true;
720        }
721        else
722        {
723          activeValues.clear();
724          pendingValues = activeValues;
725          hasPendingValues = false;
726        }
727      }
728    
729    
730    
731      /**
732       * Assigns the initial values to this configuration attribute.  This will wipe
733       * out any previous active or pending values that may have been assigned, and
734       * it will not perform any validation on those values.  This method must only
735       * be used to set the initial values for this attribute from the configuration
736       * repository and must not be called any other time.
737       *
738       * @param  values  The initial set of values to assign to this configuration
739       *                 attribute.
740       */
741      public void setInitialValues(LinkedHashSet<AttributeValue> values)
742      {
743        if (values == null)
744        {
745          values = new LinkedHashSet<AttributeValue>();
746        }
747    
748        activeValues     = values;
749        pendingValues    = values;
750        hasPendingValues = false;
751      }
752    
753    
754    
755      /**
756       * Applies the set of pending values, making them the active values for this
757       * configuration attribute.  This will not take any action if there are no
758       * pending values.
759       */
760      public void applyPendingValues()
761      {
762        if (hasPendingValues)
763        {
764          activeValues     = pendingValues;
765          hasPendingValues = false;
766        }
767      }
768    
769    
770    
771      /**
772       * Converts the provided set of strings to a corresponding set of attribute
773       * values.
774       *
775       * @param  valueStrings   The set of strings to be converted into attribute
776       *                        values.
777       * @param  allowFailures  Indicates whether the decoding process should allow
778       *                        any failures in which one or more values could be
779       *                        decoded but at least one could not.  If this is
780       *                        <CODE>true</CODE> and such a condition is acceptable
781       *                        for the underlying attribute type, then the returned
782       *                        set of values should simply not include those
783       *                        undecodable values.
784       *
785       * @return  The set of attribute values converted from the provided strings.
786       *
787       * @throws  ConfigException  If an unrecoverable problem occurs while
788       *                           performing the conversion.
789       */
790      public abstract LinkedHashSet<AttributeValue>
791                           stringsToValues(List<String> valueStrings,
792                                           boolean allowFailures)
793             throws ConfigException;
794    
795    
796    
797      /**
798       * Converts the set of active values for this configuration attribute into a
799       * set of strings that may be stored in the configuration or represented over
800       * protocol.  The string representation used by this method should be
801       * compatible with the decoding used by the <CODE>stringsToValues</CODE>
802       * method.
803       *
804       * @return  The string representations of the set of active values for this
805       *          configuration attribute.
806       */
807      public abstract List<String> activeValuesToStrings();
808    
809    
810    
811      /**
812       * Converts the set of pending values for this configuration attribute into a
813       * set of strings that may be stored in the configuration or represented over
814       * protocol.  The string representation used by this method should be
815       * compatible with the decoding used by the <CODE>stringsToValues</CODE>
816       * method.
817       *
818       * @return  The string representations of the set of pending values for this
819       *          configuration attribute, or <CODE>null</CODE> if there are no
820       *          pending values.
821       */
822      public abstract List<String> pendingValuesToStrings();
823    
824    
825    
826      /**
827       * Retrieves a new configuration attribute of this type that will contain the
828       * values from the provided attribute.
829       *
830       * @param  attributeList  The list of attributes to use to create the config
831       *                        attribute.  The list must contain either one or two
832       *                        elements, with both attributes having the same base
833       *                        name and the only option allowed is ";pending" and
834       *                        only if this attribute is one that requires admin
835       *                        action before a change may take effect.
836       *
837       * @return  The generated configuration attribute.
838       *
839       * @throws  ConfigException  If the provided attribute cannot be treated as a
840       *                           configuration attribute of this type (e.g., if
841       *                           one or more of the values of the provided
842       *                           attribute are not suitable for an attribute of
843       *                           this type, or if this configuration attribute is
844       *                           single-valued and the provided attribute has
845       *                           multiple values).
846       */
847      public abstract ConfigAttribute getConfigAttribute(List<Attribute>
848                                                              attributeList)
849             throws ConfigException;
850    
851    
852    
853      /**
854       * Retrieves a JMX attribute containing the active value set for this
855       * configuration attribute.
856       *
857       * @return  A JMX attribute containing the active value set for this
858       *          configuration attribute.
859       */
860      public abstract javax.management.Attribute toJMXAttribute();
861    
862      /**
863       * Retrieves a JMX attribute containing the pending value set for this
864       * configuration attribute.
865       *
866       * @return  A JMX attribute containing the pending value set for this
867       *          configuration attribute.
868       */
869      public abstract javax.management.Attribute toJMXAttributePending();
870    
871    
872    
873      /**
874       * Adds information about this configuration attribute to the provided JMX
875       * attribute list.  If this configuration attribute requires administrative
876       * action before changes take effect and it has a set of pending values, then
877       * two attributes should be added to the list -- one for the active value
878       * and one for the pending value.  The pending value should be named with
879       * the pending option.
880       *
881       * @param  attributeList  The attribute list to which the JMX attribute(s)
882       *                        should be added.
883       */
884      public abstract void toJMXAttribute(AttributeList attributeList);
885    
886    
887    
888      /**
889       * Adds information about this configuration attribute to the provided list in
890       * the form of a JMX <CODE>MBeanAttributeInfo</CODE> object.  If this
891       * configuration attribute requires administrative action before changes take
892       * effect and it has a set of pending values, then two attribute info objects
893       * should be added to the list -- one for the active value (which should be
894       * read-write) and one for the pending value (which should be read-only).  The
895       * pending value should be named with the pending option.
896       *
897       * @param  attributeInfoList  The list to which the attribute information
898       *                            should be added.
899       */
900      public abstract void toJMXAttributeInfo(List<MBeanAttributeInfo>
901                                                   attributeInfoList);
902    
903    
904    
905      /**
906       * Retrieves a JMX <CODE>MBeanParameterInfo</CODE> object that describes this
907       * configuration attribute.
908       *
909       * @return  A JMX <CODE>MBeanParameterInfo</CODE> object that describes this
910       *          configuration attribute.
911       */
912      public abstract MBeanParameterInfo toJMXParameterInfo();
913    
914    
915    
916      /**
917       * Attempts to set the value of this configuration attribute based on the
918       * information in the provided JMX attribute.
919       *
920       * @param  jmxAttribute  The JMX attribute to use to attempt to set the value
921       *                       of this configuration attribute.
922       *
923       * @throws  ConfigException  If the provided JMX attribute does not have an
924       *                           acceptable value for this configuration
925       *                           attribute.
926       */
927      public abstract void setValue(javax.management.Attribute jmxAttribute)
928             throws ConfigException;
929    
930    
931    
932      /**
933       * Creates a duplicate of this configuration attribute.
934       *
935       * @return  A duplicate of this configuration attribute.
936       */
937      public abstract ConfigAttribute duplicate();
938    }
939