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