Source for javax.management.openmbean.OpenMBeanAttributeInfoSupport

   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<Object> minValue;
  81: 
  82:   /**
  83:    * The maximum value of the attribute (may be <code>null</code>).
  84:    */
  85:   private Comparable<Object> 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:   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: }