Frames | No Frames |
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: }