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.  A copy of the arrays is
 144:    * taken, so later changes have no effect.
 145:    *
 146:    * @param name the name of the class this instance describes.
 147:    * @param desc a description of the bean.
 148:    * @param attribs the attribute descriptions for the bean,
 149:    *                or <code>null</code>.
 150:    * @param cons the constructor descriptions for the bean,
 151:    *             or <code>null</code>.
 152:    * @param ops the operation descriptions for the bean,
 153:    *            or <code>null</code>.
 154:    * @param notifs the notification descriptions for the bean,
 155:    *               or <code>null</code>.
 156:    */
 157:   public MBeanInfo(String name, String desc, MBeanAttributeInfo[] attribs,
 158:                    MBeanConstructorInfo[] cons, MBeanOperationInfo[] ops,
 159:                    MBeanNotificationInfo[] notifs)
 160:   {
 161:     className = name;
 162:     description = desc;
 163: 
 164:     if (attribs == null)
 165:       attributes = new MBeanAttributeInfo[0];
 166:     else
 167:       attributes = (MBeanAttributeInfo[]) attribs.clone();
 168: 
 169:     if (cons == null)
 170:       constructors = new MBeanConstructorInfo[0];
 171:     else
 172:       constructors = (MBeanConstructorInfo[]) cons.clone();
 173: 
 174:     if (ops == null)
 175:       operations = new MBeanOperationInfo[0];
 176:     else
 177:       operations = (MBeanOperationInfo[]) ops.clone();
 178: 
 179:     if (notifs == null)
 180:       notifications = new MBeanNotificationInfo[0];
 181:     else
 182:       notifications = (MBeanNotificationInfo[]) notifs.clone();
 183:   }
 184: 
 185:   /**
 186:    * Returns a shallow clone of the information.  This is
 187:    * simply a new copy of each string and a clone
 188:    * of each array, which still references the same objects,
 189:    * as obtained by the {@link Object} implementation of
 190:    * {@link Object#clone()}.  As the fields can not be
 191:    * changed, this method is only really of interest to
 192:    * subclasses which may add new mutable fields or make
 193:    * the existing ones mutable.
 194:    *
 195:    * @return a shallow clone of this {@link MBeanInfo}.
 196:    */
 197:   public Object clone()
 198:   {
 199:     MBeanInfo clone = null;
 200:     try
 201:       {
 202:         clone = (MBeanInfo) super.clone();
 203:       }
 204:     catch (CloneNotSupportedException e)
 205:       {
 206:         /* This won't happen as we implement Cloneable */
 207:       }
 208:     return clone;
 209:   }
 210: 
 211:   /**
 212:    * Compares this feature with the supplied object.  This returns
 213:    * true iff the object is an instance of {@link MBeanInfo} and
 214:    * {@link Object#equals()} returns true for a comparison of the
 215:    * class name and description, and the arrays each contain the same
 216:    * elements in the same order (but one may be longer than the
 217:    * other).
 218:    *
 219:    * @param obj the object to compare.
 220:    * @return true if the object is a {@link MBeanInfo}
 221:    *         instance,
 222:    *         <code>className.equals(object.getClassName())</code>,
 223:    *         <code>description.equals(object.getDescription())</code>
 224:    *         and the corresponding elements of the arrays are
 225:    *         equal.
 226:    */
 227:   public boolean equals(Object obj)
 228:   {
 229:     if (!(obj instanceof MBeanInfo))
 230:       return false;
 231:     if (!(super.equals(obj)))
 232:       return false;
 233:     MBeanInfo o = (MBeanInfo) obj;
 234:     MBeanAttributeInfo[] attr = o.getAttributes();
 235:     for (int a = 0; a < attributes.length; ++a)
 236:       {
 237:         if (a == attr.length)
 238:           return true;
 239:         if (!(attributes[a].equals(attr[a])))
 240:           return false;
 241:       }
 242:     MBeanConstructorInfo[] cons = o.getConstructors();
 243:     for (int a = 0; a < constructors.length; ++a)
 244:       {
 245:         if (a == cons.length)
 246:           return true;
 247:         if (!(constructors[a].equals(cons[a])))
 248:           return false;
 249:       }
 250:     MBeanOperationInfo[] ops = o.getOperations();
 251:     for (int a = 0; a < operations.length; ++a)
 252:       {
 253:         if (a == ops.length)
 254:           return true;
 255:         if (!(operations[a].equals(ops[a])))
 256:           return false;
 257:       }
 258:     MBeanNotificationInfo[] notifs = o.getNotifications();
 259:     for (int a = 0; a < notifications.length; ++a)
 260:       {
 261:         if (a == notifs.length)
 262:           return true;
 263:         if (!(notifications[a].equals(notifs[a])))
 264:           return false;
 265:       }
 266:     return (className.equals(o.getClassName()) &&
 267:             description.equals(o.getDescription()));
 268:   }
 269: 
 270:   /**
 271:    * Returns descriptions of each of the attributes provided
 272:    * by this management bean.  The returned value is a shallow
 273:    * copy of the attribute array maintained by this instance.
 274:    * Hence, changing the elements of the returned array will not
 275:    * affect the attribute array, and the elements (instances
 276:    * of the {@link MBeanAttributeInfo} class) are immutable.
 277:    *
 278:    * @return an array of {@link MBeanAttributeInfo} objects,
 279:    *         representing the attributes emitted by this
 280:    *         management bean.
 281:    */
 282:   public MBeanAttributeInfo[] getAttributes()
 283:   {
 284:     return (MBeanAttributeInfo[]) attributes.clone();
 285:   }
 286: 
 287:   /**
 288:    * Returns the class name of the management bean.
 289:    *
 290:    * @return the bean's class name.
 291:    */
 292:   public String getClassName()
 293:   {
 294:     return className;
 295:   }
 296: 
 297:   /**
 298:    * Returns descriptions of each of the constructors provided
 299:    * by this management bean.  The returned value is a shallow
 300:    * copy of the constructor array maintained by this instance.
 301:    * Hence, changing the elements of the returned array will not
 302:    * affect the constructor array, and the elements (instances
 303:    * of the {@link MBeanConstructorInfo} class) are immutable.
 304:    *
 305:    * @return an array of {@link MBeanConstructorInfo} objects,
 306:    *         representing the constructors emitted by this
 307:    *         management bean.
 308:    */
 309:   public MBeanConstructorInfo[] getConstructors()
 310:   {
 311:     return (MBeanConstructorInfo[]) constructors.clone();
 312:   }
 313: 
 314:   /**
 315:    * Returns a description of the management bean.
 316:    *
 317:    * @return the bean's description.
 318:    */
 319:   public String getDescription()
 320:   {
 321:     return description;
 322:   }
 323: 
 324:   /**
 325:    * Returns descriptions of each of the notifications emitted
 326:    * by this management bean.  The returned value is a shallow
 327:    * copy of the notification array maintained by this instance.
 328:    * Hence, changing the elements of the returned array will not
 329:    * affect the notification array, and the elements (instances
 330:    * of the {@link MBeanNotificationInfo} class) are immutable.
 331:    *
 332:    * @return an array of {@link MBeanNotificationInfo} objects,
 333:    *         representing the notifications emitted by this
 334:    *         management bean.
 335:    */
 336:   public MBeanNotificationInfo[] getNotifications()
 337:   {
 338:     return (MBeanNotificationInfo[]) notifications.clone();
 339:   }
 340: 
 341:   /**
 342:    * Returns descriptions of each of the operations provided
 343:    * by this management bean.  The returned value is a shallow
 344:    * copy of the operation array maintained by this instance.
 345:    * Hence, changing the elements of the returned array will not
 346:    * affect the operation array, and the elements (instances
 347:    * of the {@link MBeanOperationInfo} class) are immutable.
 348:    *
 349:    * @return an array of {@link MBeanOperationInfo} objects,
 350:    *         representing the operations emitted by this
 351:    *         management bean.
 352:    */
 353:   public MBeanOperationInfo[] getOperations()
 354:   {
 355:     return (MBeanOperationInfo[]) operations.clone();
 356:   }
 357: 
 358:   /**
 359:    * Returns the hashcode of the information as the sum of the
 360:    * hashcode of the classname, description and each array.
 361:    *
 362:    * @return the hashcode of the information.
 363:    */
 364:   public int hashCode()
 365:   {
 366:     return className.hashCode() + description.hashCode()
 367:       + Arrays.hashCode(attributes) + Arrays.hashCode(constructors)
 368:       + Arrays.hashCode(operations) + Arrays.hashCode(notifications);
 369:   }
 370: 
 371:   /**
 372:    * <p>
 373:    * Returns a textual representation of this instance.  This
 374:    * is constructed using the class name
 375:    * (<code>javax.management.MBeanInfo</code>),
 376:    * the name and description of the bean and the contents
 377:    * of the four arrays.
 378:    * </p>
 379:    * <p>
 380:    * As instances of this class are immutable, the return value
 381:    * is computed just once for each instance and reused
 382:    * throughout its life.
 383:    * </p>
 384:    *
 385:    * @return a @link{java.lang.String} instance representing
 386:    *         the instance in textual form.
 387:    */
 388:   public String toString()
 389:   {
 390:     if (string == null)
 391:       string = getClass().getName()
 392:         + "[name=" + className
 393:         + ",desc=" + description
 394:         + ",attributes=" + Arrays.toString(attributes)
 395:         + ",constructors=" + Arrays.toString(constructors)
 396:         + ",operations=" + Arrays.toString(operations)
 397:         + ",notifications=" + Arrays.toString(notifications)
 398:         + "]";
 399:     return string;
 400:   }
 401: 
 402: }