Source for javax.management.MBeanInfo

   1: /* MBeanInfo.java -- Information about a management bean.
   2:    Copyright (C) 2006 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;
  39: 
  40: import java.io.Serializable;
  41: 
  42: import java.util.Arrays;
  43: 
  44: /**
  45:  * <p>
  46:  * Describes the interface of a management bean.  This allows
  47:  * the user to access the bean dynamically, without knowing
  48:  * the details of any of its attributes, operations,
  49:  * constructors or notifications beforehand.  The information
  50:  * is immutable as standard.  Of course, subclasses may change
  51:  * this, but this behaviour is not recommended.
  52:  * </p>
  53:  * <p>
  54:  * The contents of this class, for standard management beans,
  55:  * are dynamically compiled using reflection.
  56:  * {@link #getClassName()} and {@link #getConstructors()}
  57:  * return the name of the class and its constructors, respectively.
  58:  * This is much the same as could be obtained by reflection on the
  59:  * bean.  {@link #getAttributes()} and {@link #getOperations()},
  60:  * however, do something more in splitting the methods of the
  61:  * class into two sets.  Those of the form, <code>getXXX</code>,
  62:  * <code>setXXX</code> and <code>isXXX</code> are taken to be
  63:  * the accessors and mutators of a series of attributes, with
  64:  * <code>XXX</code> being the attribute name.  These are returned
  65:  * by {@link getAttributes()} and the {@link Attribute} class can
  66:  * be used to manipulate them.  The remaining methods are classified
  67:  * as operations and returned by {@link getOperations()}.
  68:  * </p>
  69:  * <p>
  70:  * Beans can also broadcast notifications.  If the bean provides this
  71:  * facility, by implementing the {@link NotificationBroadcaster}
  72:  * interface, then an array of {@link MBeanNotificationInfo} objects
  73:  * may be obtained from {@link #getNotifications()}, which describe
  74:  * the notifications emitted.
  75:  * </p>
  76:  * <p>
  77:  * Model management beans and open management beans also supply an
  78:  * instance of this class, as part of implementing the
  79:  * {@link DynamicMBean#getMBeanInfo()} method of {@link DynamicMBean}.
  80:  * </p>
  81:  * 
  82:  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
  83:  * @since 1.5
  84:  */
  85: public class MBeanInfo
  86:   implements Cloneable, Serializable
  87: {
  88: 
  89:   /**
  90:    * Compatible with JDK 1.5
  91:    */
  92:   private static final long serialVersionUID = -6451021435135161911L;
  93: 
  94:   /**
  95:    * A description of the bean.
  96:    * 
  97:    * @serial The bean's description.
  98:    */
  99:   private String description;
 100: 
 101:   /**
 102:    * The class name of the management bean.
 103:    *
 104:    * @serial The bean's class name.
 105:    */
 106:   private String className;
 107: 
 108:   /**
 109:    * Descriptions of the attributes provided by the bean.
 110:    */
 111:   private MBeanAttributeInfo[] attributes;
 112: 
 113:   /**
 114:    * Descriptions of the operations provided by the bean.
 115:    */
 116:   private MBeanOperationInfo[] operations;
 117: 
 118:   /**
 119:    * Descriptions of the bean's constructors.
 120:    */
 121:   private MBeanConstructorInfo[] constructors;
 122: 
 123:   /**
 124:    * Descriptions of the notifications emitted by the bean.
 125:    *
 126:    * @serial The bean's notifications.
 127:    */
 128:   private MBeanNotificationInfo[] notifications;
 129: 
 130:   /**
 131:    * The <code>toString()</code> result of this instance.
 132:    */
 133:   private transient String string;
 134: 
 135:   /**
 136:    * Constructs a new {@link MBeanInfo} using the supplied
 137:    * class name and description with the given attributes,
 138:    * operations, constructors and notifications.  The class
 139:    * name does not have to actually specify a valid class that
 140:    * can be loaded by the MBean server or class loader; it merely
 141:    * has to be a syntactically correct class name.  Any of the
 142:    * arrays may be <code>null</code>; this will be treated as if
 143:    * an empty array was supplied.
 144:    *
 145:    * @param name the name of the class this instance describes.
 146:    * @param desc a description of the bean.
 147:    * @param attribs the attribute descriptions for the bean,
 148:    *                or <code>null</code>.
 149:    * @param cons the constructor descriptions for the bean,
 150:    *             or <code>null</code>.
 151:    * @param ops the operation descriptions for the bean,
 152:    *            or <code>null</code>.
 153:    * @param notifs the notification descriptions for the bean,
 154:    *               or <code>null</code>.
 155:    */
 156:   public MBeanInfo(String name, String desc, MBeanAttributeInfo[] attribs,
 157:            MBeanConstructorInfo[] cons, MBeanOperationInfo[] ops,
 158:            MBeanNotificationInfo[] notifs)
 159:   {
 160:     className = name;
 161:     description = desc;
 162:     if (attribs == null)
 163:       attributes = new MBeanAttributeInfo[0];
 164:     else
 165:       attributes = attribs;
 166:     if (cons == null)
 167:       constructors = new MBeanConstructorInfo[0];
 168:     else
 169:       constructors = cons;
 170:     if (ops == null)
 171:       operations = new MBeanOperationInfo[0];
 172:     else
 173:       operations = ops;
 174:     if (notifs == null)
 175:       notifications = new MBeanNotificationInfo[0];
 176:     else
 177:       notifications = notifs;
 178:   }
 179: 
 180:   /**
 181:    * Returns a shallow clone of the information.  This is
 182:    * simply a new copy of each string and a clone
 183:    * of each array, which still references the same objects,
 184:    * as obtained by the {@link Object} implementation of
 185:    * {@link Object#clone()}.  As the fields can not be
 186:    * changed, this method is only really of interest to
 187:    * subclasses which may add new mutable fields or make
 188:    * the existing ones mutable.
 189:    *
 190:    * @return a shallow clone of this {@link MBeanInfo}.
 191:    */
 192:   public Object clone()
 193:   {
 194:     MBeanInfo clone = null;
 195:     try
 196:       {
 197:     clone = (MBeanInfo) super.clone();
 198:       }
 199:     catch (CloneNotSupportedException e)
 200:       {
 201:     /* This won't happen as we implement Cloneable */
 202:       }
 203:     return clone;
 204:   }
 205: 
 206:   /**
 207:    * Compares this feature with the supplied object.  This returns
 208:    * true iff the object is an instance of {@link MBeanInfo} and
 209:    * {@link Object#equals()} returns true for a comparison of the
 210:    * class name and description, and the arrays each contain the same
 211:    * elements in the same order (but one may be longer than the
 212:    * other).
 213:    *
 214:    * @param obj the object to compare.
 215:    * @return true if the object is a {@link MBeanInfo}
 216:    *         instance, 
 217:    *         <code>className.equals(object.getClassName())</code>,
 218:    *         <code>description.equals(object.getDescription())</code>
 219:    *         and the corresponding elements of the arrays are
 220:    *         equal.
 221:    */
 222:   public boolean equals(Object obj)
 223:   {
 224:     if (!(obj instanceof MBeanInfo))
 225:       return false;
 226:     if (!(super.equals(obj)))
 227:       return false;
 228:     MBeanInfo o = (MBeanInfo) obj;
 229:     MBeanAttributeInfo[] attr = o.getAttributes();
 230:     for (int a = 0; a < attributes.length; ++a)
 231:       {
 232:     if (a == attr.length)
 233:       return true;
 234:     if (!(attributes[a].equals(attr[a])))
 235:       return false;
 236:       }
 237:     MBeanConstructorInfo[] cons = o.getConstructors();
 238:     for (int a = 0; a < constructors.length; ++a)
 239:       {
 240:     if (a == cons.length)
 241:       return true;
 242:     if (!(constructors[a].equals(cons[a])))
 243:       return false;
 244:       }
 245:     MBeanOperationInfo[] ops = o.getOperations();
 246:     for (int a = 0; a < operations.length; ++a)
 247:       {
 248:     if (a == ops.length)
 249:       return true;
 250:     if (!(operations[a].equals(ops[a])))
 251:       return false;
 252:       }
 253:     MBeanNotificationInfo[] notifs = o.getNotifications();
 254:     for (int a = 0; a < notifications.length; ++a)
 255:       {
 256:     if (a == notifs.length)
 257:       return true;
 258:     if (!(notifications[a].equals(notifs[a])))
 259:       return false;
 260:       }
 261:     return (className.equals(o.getClassName()) &&
 262:         description.equals(o.getDescription()));
 263:   }
 264: 
 265:   /**
 266:    * Returns descriptions of each of the attributes provided
 267:    * by this management bean.  The returned value is a shallow
 268:    * copy of the attribute array maintained by this instance.
 269:    * Hence, changing the elements of the returned array will not
 270:    * affect the attribute array, and the elements (instances
 271:    * of the {@link MBeanAttributeInfo} class) are immutable.
 272:    *
 273:    * @return an array of {@link MBeanAttributeInfo} objects,
 274:    *         representing the attributes emitted by this
 275:    *         management bean.
 276:    */
 277:   public MBeanAttributeInfo[] getAttributes()
 278:   {
 279:     return (MBeanAttributeInfo[]) attributes.clone();
 280:   }
 281: 
 282:   /**
 283:    * Returns the class name of the management bean.
 284:    *
 285:    * @return the bean's class name.
 286:    */
 287:   public String getClassName()
 288:   {
 289:     return className;
 290:   }
 291: 
 292:   /**
 293:    * Returns descriptions of each of the constructors provided
 294:    * by this management bean.  The returned value is a shallow
 295:    * copy of the constructor array maintained by this instance.
 296:    * Hence, changing the elements of the returned array will not
 297:    * affect the constructor array, and the elements (instances
 298:    * of the {@link MBeanConstructorInfo} class) are immutable.
 299:    *
 300:    * @return an array of {@link MBeanConstructorInfo} objects,
 301:    *         representing the constructors emitted by this
 302:    *         management bean.
 303:    */
 304:   public MBeanConstructorInfo[] getConstructors()
 305:   {
 306:     return (MBeanConstructorInfo[]) constructors.clone();
 307:   }
 308: 
 309:   /**
 310:    * Returns a description of the management bean.
 311:    *
 312:    * @return the bean's description.
 313:    */
 314:   public String getDescription()
 315:   {
 316:     return description;
 317:   }
 318: 
 319:   /**
 320:    * Returns descriptions of each of the notifications emitted
 321:    * by this management bean.  The returned value is a shallow
 322:    * copy of the notification array maintained by this instance.
 323:    * Hence, changing the elements of the returned array will not
 324:    * affect the notification array, and the elements (instances
 325:    * of the {@link MBeanNotificationInfo} class) are immutable.
 326:    *
 327:    * @return an array of {@link MBeanNotificationInfo} objects,
 328:    *         representing the notifications emitted by this
 329:    *         management bean.
 330:    */
 331:   public MBeanNotificationInfo[] getNotifications()
 332:   {
 333:     return (MBeanNotificationInfo[]) notifications.clone();
 334:   }
 335: 
 336:   /**
 337:    * Returns descriptions of each of the operations provided
 338:    * by this management bean.  The returned value is a shallow
 339:    * copy of the operation array maintained by this instance.
 340:    * Hence, changing the elements of the returned array will not
 341:    * affect the operation array, and the elements (instances
 342:    * of the {@link MBeanOperationInfo} class) are immutable.
 343:    *
 344:    * @return an array of {@link MBeanOperationInfo} objects,
 345:    *         representing the operations emitted by this
 346:    *         management bean.
 347:    */
 348:   public MBeanOperationInfo[] getOperations()
 349:   {
 350:     return (MBeanOperationInfo[]) operations.clone();
 351:   }
 352: 
 353:   /**
 354:    * Returns the hashcode of the information as the sum of the
 355:    * hashcode of the classname, description and each array.
 356:    *
 357:    * @return the hashcode of the information.
 358:    */
 359:   public int hashCode()
 360:   {
 361:     return className.hashCode() + description.hashCode()
 362:       + Arrays.hashCode(attributes) + Arrays.hashCode(constructors)
 363:       + Arrays.hashCode(operations) + Arrays.hashCode(notifications);
 364:   }
 365: 
 366:   /**
 367:    * <p>
 368:    * Returns a textual representation of this instance.  This
 369:    * is constructed using the class name
 370:    * (<code>javax.management.MBeanInfo</code>),
 371:    * the name and description of the bean and the contents
 372:    * of the four arrays.
 373:    * </p>
 374:    * <p>
 375:    * As instances of this class are immutable, the return value
 376:    * is computed just once for each instance and reused
 377:    * throughout its life.
 378:    * </p>
 379:    *
 380:    * @return a @link{java.lang.String} instance representing
 381:    *         the instance in textual form.
 382:    */
 383:   public String toString()
 384:   {
 385:     if (string == null)
 386:       string = getClass().getName()
 387:     + "[name=" + className 
 388:     + ",desc=" + description 
 389:     + ",attributes=" + Arrays.toString(attributes)
 390:     + ",constructors=" + Arrays.toString(constructors)
 391:     + ",operations=" + Arrays.toString(operations)
 392:     + ",notifications=" + Arrays.toString(notifications)
 393:     + "]";
 394:     return string;
 395:   }
 396: 
 397: }