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<?> 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: }