001 /* OpenMBeanAttributeInfoSupport.java -- Open typed info about an attribute. 002 Copyright (C) 2006, 2007 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 package javax.management.openmbean; 039 040 import java.util.Collections; 041 import java.util.HashSet; 042 import java.util.Set; 043 044 import javax.management.MBeanAttributeInfo; 045 046 /** 047 * Describes an attribute of an open management bean. 048 * 049 * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 050 * @since 1.5 051 */ 052 public class OpenMBeanAttributeInfoSupport 053 extends MBeanAttributeInfo 054 implements OpenMBeanAttributeInfo 055 { 056 057 /** 058 * Compatible with JDK 1.5 059 */ 060 private static final long serialVersionUID = -4867215622149721849L; 061 062 /** 063 * The open type of the attribute. 064 */ 065 private OpenType<?> openType; 066 067 /** 068 * The default value of the attribute (may be <code>null</code>). 069 */ 070 private Object defaultValue; 071 072 /** 073 * The possible legal values of the attribute (may be <code>null</code>). 074 */ 075 private Set<?> legalValues; 076 077 /** 078 * The minimum value of the attribute (may be <code>null</code>). 079 */ 080 private Comparable<Object> minValue; 081 082 /** 083 * The maximum value of the attribute (may be <code>null</code>). 084 */ 085 private Comparable<Object> maxValue; 086 087 /** 088 * The hash code of this instance. 089 */ 090 private transient Integer hashCode; 091 092 /** 093 * The <code>toString()</code> result of this instance. 094 */ 095 private transient String string; 096 097 /** 098 * Constructs a new {@link OpenMBeanAttributeInfo} using the 099 * 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 public <T> OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, 207 boolean isReadable, boolean isWritable, 208 boolean isIs, T defaultValue, 209 Comparable<T> minimumValue, 210 Comparable<T> maximumValue) 211 throws OpenDataException 212 { 213 this(name, desc, type, isReadable, isWritable, isIs); 214 if (defaultValue != null && !(type.isValue(defaultValue))) 215 throw new OpenDataException("The default value is not a member of the " + 216 "open type given."); 217 if (minimumValue != null && !(type.isValue(minimumValue))) 218 throw new OpenDataException("The minimum value is not a member of the " + 219 "open type given."); 220 if (maximumValue != null && !(type.isValue(maximumValue))) 221 throw new OpenDataException("The maximum value is not a member of the " + 222 "open type given."); 223 if (defaultValue != null && (type instanceof ArrayType || 224 type instanceof TabularType)) 225 throw new OpenDataException("Default values are not applicable for " + 226 "array or tabular types."); 227 if (minValue != null && maxValue != null 228 && minValue.compareTo(maxValue) > 0) 229 throw new OpenDataException("The minimum value is greater than the " + 230 "maximum."); 231 if (minValue != null && defaultValue != null 232 && minValue.compareTo(defaultValue) > 0) 233 throw new OpenDataException("The minimum value is greater than the " + 234 "default."); 235 if (defaultValue != null && maxValue != null 236 && maxValue.compareTo(defaultValue) < 0) 237 throw new OpenDataException("The default value is greater than the " + 238 "maximum."); 239 240 openType = type; 241 this.defaultValue = defaultValue; 242 minValue = (Comparable<Object>) minimumValue; 243 maxValue = (Comparable<Object>) maximumValue; 244 } 245 246 /** 247 * <p> 248 * Constructs a new {@link OpenMBeanAttributeInfo} using the 249 * specified name, description, open type, access properties, default 250 * value and set of legal values. The name, description and open type 251 * cannot be <code>null</code> and the name and description may not be 252 * equal to the empty string. The default, maximum and minimum values 253 * may be <code>null</code>. The following conditions apply when the 254 * attributes mentioned are non-null: 255 * </p> 256 * <ul> 257 * <li>The default value and each of the legal values must be a valid 258 * value for the given open type.</li> 259 * <li>Default and legal values are not applicable to the open types, {@link 260 * ArrayType} and {@link TabularType}.</li> 261 * <li>The default value is not in the set of legal values.</li> 262 * </ul> 263 * <p> 264 * The legal values are copied from the array into a unmodifiable set, 265 * so future modifications to the array have no effect. 266 * </p> 267 * 268 * @param name the name of the attribute. 269 * @param desc a description of the attribute. 270 * @param type the open type of the attribute. 271 * @param isReadable true if the attribute's value can be read. 272 * @param isWritable true if the attribute's value can be changed. 273 * @param isIs true if the attribute uses an accessor of the form isXXX. 274 * @param defaultValue the default value of the attribute, or <code>null</code>. 275 * @param legalValues the legal values of the attribute. May be 276 * <code>null</code> or an empty array. 277 * @throws IllegalArgumentException if the name, description or 278 * open type are <code>null</code> 279 * or the name or description are 280 * the empty string. 281 * @throws OpenDataException if any condition in the list above is broken. 282 */ 283 public <T> OpenMBeanAttributeInfoSupport(String name, String desc, OpenType<T> type, 284 boolean isReadable, boolean isWritable, 285 boolean isIs, T defaultValue, 286 T[] legalValues) 287 throws OpenDataException 288 { 289 this(name, desc, type, isReadable, isWritable, isIs); 290 if (defaultValue != null && !(type.isValue(defaultValue))) 291 throw new OpenDataException("The default value is not a member of the " + 292 "open type given."); 293 if (defaultValue != null && (type instanceof ArrayType || 294 type instanceof TabularType)) 295 throw new OpenDataException("Default values are not applicable for " + 296 "array or tabular types."); 297 if (legalValues != null && (type instanceof ArrayType || 298 type instanceof TabularType)) 299 throw new OpenDataException("Legal values are not applicable for " + 300 "array or tabular types."); 301 if (legalValues != null && legalValues.length > 0) 302 { 303 Set lv = new HashSet(legalValues.length); 304 for (int a = 0; a < legalValues.length; ++a) 305 { 306 if (legalValues[a] != null && 307 !(type.isValue(legalValues[a]))) 308 throw new OpenDataException("The legal value, " 309 + legalValues[a] + 310 "is not a member of the " + 311 "open type given."); 312 lv.add(legalValues[a]); 313 } 314 if (defaultValue != null && !(lv.contains(defaultValue))) 315 throw new OpenDataException("The default value is not in the set " + 316 "of legal values."); 317 this.legalValues = Collections.unmodifiableSet(lv); 318 } 319 openType = type; 320 this.defaultValue = defaultValue; 321 } 322 323 /** 324 * Compares this attribute with the supplied object. This returns 325 * true iff the object is an instance of {@link OpenMBeanAttributeInfo} 326 * with an equal name and open type and the same default, minimum, 327 * maximum and legal values and the same access properties. 328 * 329 * @param obj the object to compare. 330 * @return true if the object is a {@link OpenMBeanAttributeInfo} 331 * instance, 332 * <code>name.equals(object.getName())</code>, 333 * <code>openType.equals(object.getOpenType())</code>, 334 * <code>isRead == object.isReadable()</code>, 335 * <code>isWrite == object.isWritable()</code>, 336 * <code>isIs == object.isIs()</code>, 337 * <code>defaultValue.equals(object.getDefaultValue())</code>, 338 * <code>minValue.equals(object.getMinValue())</code>, 339 * <code>maxValue.equals(object.getMaxValue())</code>, 340 * and <code>legalValues.equals(object.getLegalValues())</code>. 341 */ 342 public boolean equals(Object obj) 343 { 344 if (!(obj instanceof OpenMBeanAttributeInfo)) 345 return false; 346 OpenMBeanAttributeInfo o = (OpenMBeanAttributeInfo) obj; 347 return getName().equals(o.getName()) && 348 openType.equals(o.getOpenType()) && 349 isReadable() == o.isReadable() && 350 isWritable() == o.isWritable() && 351 isIs() == o.isIs() && 352 (defaultValue == null ? o.getDefaultValue() == null : 353 defaultValue.equals(o.getDefaultValue())) && 354 (minValue == null ? o.getMinValue() == null : 355 minValue.equals(o.getMinValue())) && 356 (maxValue == null ? o.getMaxValue() == null : 357 maxValue.equals(o.getMaxValue())) && 358 (legalValues == null ? o.getLegalValues() == null : 359 legalValues.equals(o.getLegalValues())); 360 } 361 362 /** 363 * Returns the default value of this attribute, or <code>null</code> 364 * if there is no default value. 365 * 366 * @return the default value of the attribute, or <code>null</code> 367 * if there is no default. 368 */ 369 public Object getDefaultValue() 370 { 371 return defaultValue; 372 } 373 374 /** 375 * Returns a {@link java.util.Set} enumerating the legal values 376 * of this attribute, or <code>null</code> if no such limited 377 * set exists for this attribute. 378 * 379 * @return a set of legal values, or <code>null</code> if no such 380 * set exists. 381 */ 382 public Set<?> getLegalValues() 383 { 384 return legalValues; 385 } 386 387 /** 388 * Returns the maximum value of this attribute, or <code>null</code> 389 * if there is no maximum. 390 * 391 * @return the maximum value, or <code>null</code> if none exists. 392 */ 393 public Comparable<?> getMaxValue() 394 { 395 return maxValue; 396 } 397 398 /** 399 * Returns the minimum value of this attribute, or <code>null</code> 400 * if there is no minimum. 401 * 402 * @return the minimum value, or <code>null</code> if none exists. 403 */ 404 public Comparable<?> getMinValue() 405 { 406 return minValue; 407 } 408 409 /** 410 * Returns the open type instance which represents the type of this 411 * attribute. 412 * 413 * @return the open type of this attribute. 414 */ 415 public OpenType<?> getOpenType() 416 { 417 return openType; 418 } 419 420 /** 421 * Returns true if this attribute has a default value 422 * (i.e. the value is non-null). 423 * 424 * @return true if this attribute has a default. 425 */ 426 public boolean hasDefaultValue() 427 { 428 return defaultValue != null; 429 } 430 431 /** 432 * <p> 433 * Returns the hashcode of the attribute information as the sum of 434 * the hashcodes of the name, open type, default value, maximum 435 * value, minimum value and the set of legal values. 436 * </p> 437 * <p> 438 * As instances of this class are immutable, the hash code 439 * is computed just once for each instance and reused 440 * throughout its life. 441 * </p> 442 * 443 * @return the hashcode of the attribute information. 444 */ 445 public int hashCode() 446 { 447 if (hashCode == null) 448 hashCode = Integer.valueOf(getName().hashCode() + 449 openType.hashCode() + 450 Boolean.valueOf(isReadable()).hashCode() + 451 (2 * 452 Boolean.valueOf(isWritable()).hashCode()) + 453 (4 * Boolean.valueOf(isIs()).hashCode()) + 454 (defaultValue == null ? 0 : 455 defaultValue.hashCode()) + 456 (minValue == null ? 0 : 457 minValue.hashCode()) + 458 (maxValue == null ? 0 : 459 maxValue.hashCode()) + 460 (legalValues == null ? 0 : 461 legalValues.hashCode())); 462 return hashCode.intValue(); 463 } 464 465 /** 466 * Returns true if there is a set of legal values for this 467 * attribute (i.e. the value is non-null). 468 * 469 * @return true if a set of legal values exists for this 470 * attribute. 471 */ 472 public boolean hasLegalValues() 473 { 474 return legalValues != null; 475 } 476 477 /** 478 * Returns true if there is a maximum value for this attribute 479 * (i.e. the value is non-null). 480 * 481 * @return true if a maximum value exists for this attribute. 482 */ 483 public boolean hasMaxValue() 484 { 485 return maxValue != null; 486 } 487 488 /** 489 * Returns true if there is a minimum value for this attribute. 490 * (i.e. the value is non-null). 491 * 492 * @return true if a minimum value exists for this attribute. 493 */ 494 public boolean hasMinValue() 495 { 496 return minValue != null; 497 } 498 499 /** 500 * Returns true if the specified object is a valid value for 501 * this attribute. 502 * 503 * @param obj the object to test. 504 * @return true if <code>obj</code> is a valid value for this 505 * attribute. 506 */ 507 public boolean isValue(Object obj) 508 { 509 return openType.isValue(obj); 510 } 511 512 /** 513 * <p> 514 * Returns a textual representation of this instance. This 515 * is constructed using the class name 516 * (<code>javax.management.openmbean.OpenMBeanAttributeInfo</code>) 517 * along with the name, open type, access properties, default, 518 * minimum, maximum and legal values of the attribute. 519 * </p> 520 * <p> 521 * As instances of this class are immutable, the return value 522 * is computed just once for each instance and reused 523 * throughout its life. 524 * </p> 525 * 526 * @return a @link{java.lang.String} instance representing 527 * the instance in textual form. 528 */ 529 public String toString() 530 { 531 if (string == null) 532 string = getClass().getName() 533 + "[name=" + getName() 534 + ",openType=" + openType 535 + ",isReadable=" + isReadable() 536 + ",isWritable=" + isWritable() 537 + ",isIs=" + isIs() 538 + ",defaultValue=" + defaultValue 539 + ",minValue=" + minValue 540 + ",maxValue=" + maxValue 541 + ",legalValues=" + legalValues 542 + "]"; 543 return string; 544 } 545 546 }