Frames | No Frames |
1: /* OpenMBeanAttributeInfoSupport.java -- Open typed info about an attribute. 2: Copyright (C) 2006, 2007 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: package javax.management.openmbean; 39: 40: import java.util.Collections; 41: import java.util.HashSet; 42: import java.util.Set; 43: 44: import javax.management.MBeanAttributeInfo; 45: 46: /** 47: * Describes an attribute of an open management bean. 48: * 49: * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 50: * @since 1.5 51: */ 52: public class OpenMBeanAttributeInfoSupport 53: extends MBeanAttributeInfo 54: implements OpenMBeanAttributeInfo 55: { 56: 57: /** 58: * Compatible with JDK 1.5 59: */ 60: private static final long serialVersionUID = -4867215622149721849L; 61: 62: /** 63: * The open type of the attribute. 64: */ 65: private OpenType<?> openType; 66: 67: /** 68: * The default value of the attribute (may be <code>null</code>). 69: */ 70: private Object defaultValue; 71: 72: /** 73: * The possible legal values of the attribute (may be <code>null</code>). 74: */ 75: private Set<?> legalValues; 76: 77: /** 78: * The minimum value of the attribute (may be <code>null</code>). 79: */ 80: private Comparable<?> minValue; 81: 82: /** 83: * The maximum value of the attribute (may be <code>null</code>). 84: */ 85: private Comparable<?> maxValue; 86: 87: /** 88: * The hash code of this instance. 89: */ 90: private transient Integer hashCode; 91: 92: /** 93: * The <code>toString()</code> result of this instance. 94: */ 95: private transient String string; 96: 97: /** 98: * Constructs a new {@link OpenMBeanAttributeInfo} using the 99: * specified name, description, open type and access properties. 100: * The name, description and open type may not be <code>null</code> 101: * and the name and description may not be equal to the empty 102: * string. 103: * 104: * @param name the name of the attribute. 105: * @param desc a description of the attribute. 106: * @param type the open type of the attribute. 107: * @param isReadable true if the attribute's value can be read. 108: * @param isWritable true if the attribute's value can be changed. 109: * @param isIs true if the attribute uses an accessor of the form isXXX. 110: * @throws IllegalArgumentException if the name, description or 111: * open type are <code>null</code> 112: * or the name or description are 113: * the empty string. 114: */ 115: public OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<?> type, 116: boolean isReadable, boolean isWritable, 117: boolean isIs) 118: { 119: super(name, type == null ? null : type.getClassName(), desc, isReadable, 120: isWritable, isIs); 121: if (name == null) 122: throw new IllegalArgumentException("The name may not be null."); 123: if (desc == null) 124: throw new IllegalArgumentException("The description may not be null."); 125: if (type == null) 126: throw new IllegalArgumentException("The type may not be null."); 127: if (name.length() == 0) 128: throw new IllegalArgumentException("The name may not be the empty string."); 129: if (desc.length() == 0) 130: throw new IllegalArgumentException("The description may not be the " + 131: "empty string."); 132: } 133: 134: /** 135: * Constructs a new {@link OpenMBeanAttributeInfo} using the 136: * specified name, description, open type and default value. The 137: * name, description and open type cannot be <code>null</code> and 138: * the name and description may not be equal to the empty string. 139: * The default value may be <code>null</code>. If non-null, it must 140: * be a valid value of the given open type. Default values are not 141: * applicable to the open types, {@link ArrayType} and {@link 142: * TabularType}. 143: * 144: * @param name the name of the attribute. 145: * @param desc a description of the attribute. 146: * @param type the open type of the attribute. 147: * @param isReadable true if the attribute's value can be read. 148: * @param isWritable true if the attribute's value can be changed. 149: * @param isIs true if the attribute uses an accessor of the form isXXX. 150: * @param defaultValue the default value of the attribute. 151: * @throws IllegalArgumentException if the name, description or 152: * open type are <code>null</code> 153: * or the name or description are 154: * the empty string. 155: * @throws OpenDataException if <code>defaultValue<code> is non-null 156: * and is either not a value of the given 157: * open type or the open type is an instance 158: * of {@link ArrayType} or {@link TabularType}. 159: */ 160: public <T> OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, 161: boolean isReadable, boolean isWritable, 162: boolean isIs, T defaultValue) 163: throws OpenDataException 164: { 165: this(name, desc, type, isReadable, isWritable, isIs, defaultValue, null); 166: } 167: 168: /** 169: * <p> 170: * Constructs a new {@link OpenMBeanAttributeInfo} using the 171: * specified name, description, open type, access properties, 172: * default, maximum and minimum values. The name, description 173: * and open type cannot be <code>null</code> and the name and 174: * description may not be equal to the empty string. The 175: * default, maximum and minimum values may be <code>null</code>. 176: * The following conditions apply when the attributes mentioned 177: * are non-null: 178: * </p> 179: * <ul> 180: * <li>The values must be valid values for the given open type.</li> 181: * <li>Default values are not applicable to the open types, {@link 182: * ArrayType} and {@link TabularType}.</li> 183: * <li>The minimum value must be smaller than or equal to the maximum value 184: * (literally, <code>minValue.compareTo(maxValue) <= 0</code>.</li> 185: * <li>The minimum value must be smaller than or equal to the default value 186: * (literally, <code>minValue.compareTo(defaultValue) <= 0</code>.</li> 187: * <li>The default value must be smaller than or equal to the maximum value 188: * (literally, <code>defaultValue.compareTo(maxValue) <= 0</code>.</li> 189: * </ul> 190: * 191: * @param name the name of the attribute. 192: * @param desc a description of the attribute. 193: * @param type the open type of the attribute. 194: * @param isReadable true if the attribute's value can be read. 195: * @param isWritable true if the attribute's value can be changed. 196: * @param isIs true if the attribute uses an accessor of the form isXXX. 197: * @param defaultValue the default value of the attribute, or <code>null</code>. 198: * @param minimumValue the minimum value of the attribute, or <code>null</code>. 199: * @param maximumValue the maximum value of the attribute, or <code>null</code>. 200: * @throws IllegalArgumentException if the name, description or 201: * open type are <code>null</code> 202: * or the name or description are 203: * the empty string. 204: * @throws OpenDataException if any condition in the list above is broken. 205: */ 206: @SuppressWarnings("unchecked") 207: public <T> OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, 208: boolean isReadable, boolean isWritable, 209: boolean isIs, T defaultValue, 210: Comparable<T> minimumValue, 211: Comparable<T> maximumValue) 212: throws OpenDataException 213: { 214: this(name, desc, type, isReadable, isWritable, isIs); 215: if (defaultValue != null && !(type.isValue(defaultValue))) 216: throw new OpenDataException("The default value is not a member of the " + 217: "open type given."); 218: if (minimumValue != null && !(type.isValue(minimumValue))) 219: throw new OpenDataException("The minimum value is not a member of the " + 220: "open type given."); 221: if (maximumValue != null && !(type.isValue(maximumValue))) 222: throw new OpenDataException("The maximum value is not a member of the " + 223: "open type given."); 224: if (defaultValue != null && (type instanceof ArrayType || 225: type instanceof TabularType)) 226: throw new OpenDataException("Default values are not applicable for " + 227: "array or tabular types."); 228: if (minimumValue != null && maximumValue != null 229: && minimumValue.compareTo((T) maximumValue) > 0) 230: throw new OpenDataException("The minimum value is greater than the " + 231: "maximum."); 232: if (minimumValue != null && defaultValue != null 233: && minimumValue.compareTo(defaultValue) > 0) 234: throw new OpenDataException("The minimum value is greater than the " + 235: "default."); 236: if (defaultValue != null && maximumValue != null 237: && maximumValue.compareTo(defaultValue) < 0) 238: throw new OpenDataException("The default value is greater than the " + 239: "maximum."); 240: 241: openType = type; 242: this.defaultValue = defaultValue; 243: minValue = minimumValue; 244: maxValue = maximumValue; 245: } 246: 247: /** 248: * <p> 249: * Constructs a new {@link OpenMBeanAttributeInfo} using the 250: * specified name, description, open type, access properties, default 251: * value and set of legal values. The name, description and open type 252: * cannot be <code>null</code> and the name and description may not be 253: * equal to the empty string. The default, maximum and minimum values 254: * may be <code>null</code>. The following conditions apply when the 255: * attributes mentioned are non-null: 256: * </p> 257: * <ul> 258: * <li>The default value and each of the legal values must be a valid 259: * value for the given open type.</li> 260: * <li>Default and legal values are not applicable to the open types, {@link 261: * ArrayType} and {@link TabularType}.</li> 262: * <li>The default value is not in the set of legal values.</li> 263: * </ul> 264: * <p> 265: * The legal values are copied from the array into a unmodifiable set, 266: * so future modifications to the array have no effect. 267: * </p> 268: * 269: * @param name the name of the attribute. 270: * @param desc a description of the attribute. 271: * @param type the open type of the attribute. 272: * @param isReadable true if the attribute's value can be read. 273: * @param isWritable true if the attribute's value can be changed. 274: * @param isIs true if the attribute uses an accessor of the form isXXX. 275: * @param defaultValue the default value of the attribute, or <code>null</code>. 276: * @param legalValues the legal values of the attribute. May be 277: * <code>null</code> or an empty array. 278: * @throws IllegalArgumentException if the name, description or 279: * open type are <code>null</code> 280: * or the name or description are 281: * the empty string. 282: * @throws OpenDataException if any condition in the list above is broken. 283: */ 284: public <T> OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, 285: boolean isReadable, boolean isWritable, 286: boolean isIs, T defaultValue, 287: T[] legalValues) 288: throws OpenDataException 289: { 290: this(name, desc, type, isReadable, isWritable, isIs); 291: if (defaultValue != null && !(type.isValue(defaultValue))) 292: throw new OpenDataException("The default value is not a member of the " + 293: "open type given."); 294: if (defaultValue != null && (type instanceof ArrayType || 295: type instanceof TabularType)) 296: throw new OpenDataException("Default values are not applicable for " + 297: "array or tabular types."); 298: if (legalValues != null && (type instanceof ArrayType || 299: type instanceof TabularType)) 300: throw new OpenDataException("Legal values are not applicable for " + 301: "array or tabular types."); 302: if (legalValues != null && legalValues.length > 0) 303: { 304: Set<T> lv = new HashSet<T>(legalValues.length); 305: for (int a = 0; a < legalValues.length; ++a) 306: { 307: if (legalValues[a] != null && 308: !(type.isValue(legalValues[a]))) 309: throw new OpenDataException("The legal value, " 310: + legalValues[a] + 311: "is not a member of the " + 312: "open type given."); 313: lv.add(legalValues[a]); 314: } 315: if (defaultValue != null && !(lv.contains(defaultValue))) 316: throw new OpenDataException("The default value is not in the set " + 317: "of legal values."); 318: this.legalValues = Collections.unmodifiableSet(lv); 319: } 320: openType = type; 321: this.defaultValue = defaultValue; 322: } 323: 324: /** 325: * Compares this attribute with the supplied object. This returns 326: * true iff the object is an instance of {@link OpenMBeanAttributeInfo} 327: * with an equal name and open type and the same default, minimum, 328: * maximum and legal values and the same access properties. 329: * 330: * @param obj the object to compare. 331: * @return true if the object is a {@link OpenMBeanAttributeInfo} 332: * instance, 333: * <code>name.equals(object.getName())</code>, 334: * <code>openType.equals(object.getOpenType())</code>, 335: * <code>isRead == object.isReadable()</code>, 336: * <code>isWrite == object.isWritable()</code>, 337: * <code>isIs == object.isIs()</code>, 338: * <code>defaultValue.equals(object.getDefaultValue())</code>, 339: * <code>minValue.equals(object.getMinValue())</code>, 340: * <code>maxValue.equals(object.getMaxValue())</code>, 341: * and <code>legalValues.equals(object.getLegalValues())</code>. 342: */ 343: public boolean equals(Object obj) 344: { 345: if (!(obj instanceof OpenMBeanAttributeInfo)) 346: return false; 347: OpenMBeanAttributeInfo o = (OpenMBeanAttributeInfo) obj; 348: return getName().equals(o.getName()) && 349: openType.equals(o.getOpenType()) && 350: isReadable() == o.isReadable() && 351: isWritable() == o.isWritable() && 352: isIs() == o.isIs() && 353: (defaultValue == null ? o.getDefaultValue() == null : 354: defaultValue.equals(o.getDefaultValue())) && 355: (minValue == null ? o.getMinValue() == null : 356: minValue.equals(o.getMinValue())) && 357: (maxValue == null ? o.getMaxValue() == null : 358: maxValue.equals(o.getMaxValue())) && 359: (legalValues == null ? o.getLegalValues() == null : 360: legalValues.equals(o.getLegalValues())); 361: } 362: 363: /** 364: * Returns the default value of this attribute, or <code>null</code> 365: * if there is no default value. 366: * 367: * @return the default value of the attribute, or <code>null</code> 368: * if there is no default. 369: */ 370: public Object getDefaultValue() 371: { 372: return defaultValue; 373: } 374: 375: /** 376: * Returns a {@link java.util.Set} enumerating the legal values 377: * of this attribute, or <code>null</code> if no such limited 378: * set exists for this attribute. 379: * 380: * @return a set of legal values, or <code>null</code> if no such 381: * set exists. 382: */ 383: public Set<?> getLegalValues() 384: { 385: return legalValues; 386: } 387: 388: /** 389: * Returns the maximum value of this attribute, or <code>null</code> 390: * if there is no maximum. 391: * 392: * @return the maximum value, or <code>null</code> if none exists. 393: */ 394: public Comparable<?> getMaxValue() 395: { 396: return maxValue; 397: } 398: 399: /** 400: * Returns the minimum value of this attribute, or <code>null</code> 401: * if there is no minimum. 402: * 403: * @return the minimum value, or <code>null</code> if none exists. 404: */ 405: public Comparable<?> getMinValue() 406: { 407: return minValue; 408: } 409: 410: /** 411: * Returns the open type instance which represents the type of this 412: * attribute. 413: * 414: * @return the open type of this attribute. 415: */ 416: public OpenType<?> getOpenType() 417: { 418: return openType; 419: } 420: 421: /** 422: * Returns true if this attribute has a default value 423: * (i.e. the value is non-null). 424: * 425: * @return true if this attribute has a default. 426: */ 427: public boolean hasDefaultValue() 428: { 429: return defaultValue != null; 430: } 431: 432: /** 433: * <p> 434: * Returns the hashcode of the attribute information as the sum of 435: * the hashcodes of the name, open type, default value, maximum 436: * value, minimum value and the set of legal values. 437: * </p> 438: * <p> 439: * As instances of this class are immutable, the hash code 440: * is computed just once for each instance and reused 441: * throughout its life. 442: * </p> 443: * 444: * @return the hashcode of the attribute information. 445: */ 446: public int hashCode() 447: { 448: if (hashCode == null) 449: hashCode = Integer.valueOf(getName().hashCode() + 450: openType.hashCode() + 451: Boolean.valueOf(isReadable()).hashCode() + 452: (2 * 453: Boolean.valueOf(isWritable()).hashCode()) + 454: (4 * Boolean.valueOf(isIs()).hashCode()) + 455: (defaultValue == null ? 0 : 456: defaultValue.hashCode()) + 457: (minValue == null ? 0 : 458: minValue.hashCode()) + 459: (maxValue == null ? 0 : 460: maxValue.hashCode()) + 461: (legalValues == null ? 0 : 462: legalValues.hashCode())); 463: return hashCode.intValue(); 464: } 465: 466: /** 467: * Returns true if there is a set of legal values for this 468: * attribute (i.e. the value is non-null). 469: * 470: * @return true if a set of legal values exists for this 471: * attribute. 472: */ 473: public boolean hasLegalValues() 474: { 475: return legalValues != null; 476: } 477: 478: /** 479: * Returns true if there is a maximum value for this attribute 480: * (i.e. the value is non-null). 481: * 482: * @return true if a maximum value exists for this attribute. 483: */ 484: public boolean hasMaxValue() 485: { 486: return maxValue != null; 487: } 488: 489: /** 490: * Returns true if there is a minimum value for this attribute. 491: * (i.e. the value is non-null). 492: * 493: * @return true if a minimum value exists for this attribute. 494: */ 495: public boolean hasMinValue() 496: { 497: return minValue != null; 498: } 499: 500: /** 501: * Returns true if the specified object is a valid value for 502: * this attribute. 503: * 504: * @param obj the object to test. 505: * @return true if <code>obj</code> is a valid value for this 506: * attribute. 507: */ 508: public boolean isValue(Object obj) 509: { 510: return openType.isValue(obj); 511: } 512: 513: /** 514: * <p> 515: * Returns a textual representation of this instance. This 516: * is constructed using the class name 517: * (<code>javax.management.openmbean.OpenMBeanAttributeInfo</code>) 518: * along with the name, open type, access properties, default, 519: * minimum, maximum and legal values of the attribute. 520: * </p> 521: * <p> 522: * As instances of this class are immutable, the return value 523: * is computed just once for each instance and reused 524: * throughout its life. 525: * </p> 526: * 527: * @return a @link{java.lang.String} instance representing 528: * the instance in textual form. 529: */ 530: public String toString() 531: { 532: if (string == null) 533: string = getClass().getName() 534: + "[name=" + getName() 535: + ",openType=" + openType 536: + ",isReadable=" + isReadable() 537: + ",isWritable=" + isWritable() 538: + ",isIs=" + isIs() 539: + ",defaultValue=" + defaultValue 540: + ",minValue=" + minValue 541: + ",maxValue=" + maxValue 542: + ",legalValues=" + legalValues 543: + "]"; 544: return string; 545: } 546: 547: }