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 */ OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<?> type, boolean isReadable, boolean isWritable, boolean isIs)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 */ OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, boolean isReadable, boolean isWritable, boolean isIs, T defaultValue)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") OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, boolean isReadable, boolean isWritable, boolean isIs, T defaultValue, Comparable<T> minimumValue, Comparable<T> maximumValue)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 */ OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, boolean isReadable, boolean isWritable, boolean isIs, T defaultValue, T[] legalValues)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 */ equals(Object obj)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 */ getDefaultValue()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 */ getLegalValues()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 */ getMaxValue()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 */ getMinValue()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 */ getOpenType()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 */ hasDefaultValue()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 */ hashCode()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 */ hasLegalValues()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 */ hasMaxValue()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 */ hasMinValue()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 */ isValue(Object obj)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 */ toString()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 } 548