001/* MBeanInfo.java -- Information about a management bean. 002 Copyright (C) 2006 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038package javax.management; 039 040import java.io.Serializable; 041 042import java.util.Arrays; 043 044/** 045 * <p> 046 * Describes the interface of a management bean. This allows 047 * the user to access the bean dynamically, without knowing 048 * the details of any of its attributes, operations, 049 * constructors or notifications beforehand. The information 050 * is immutable as standard. Of course, subclasses may change 051 * this, but this behaviour is not recommended. 052 * </p> 053 * <p> 054 * The contents of this class, for standard management beans, 055 * are dynamically compiled using reflection. 056 * {@link #getClassName()} and {@link #getConstructors()} 057 * return the name of the class and its constructors, respectively. 058 * This is much the same as could be obtained by reflection on the 059 * bean. {@link #getAttributes()} and {@link #getOperations()}, 060 * however, do something more in splitting the methods of the 061 * class into two sets. Those of the form, <code>getXXX</code>, 062 * <code>setXXX</code> and <code>isXXX</code> are taken to be 063 * the accessors and mutators of a series of attributes, with 064 * <code>XXX</code> being the attribute name. These are returned 065 * by {@link getAttributes()} and the {@link Attribute} class can 066 * be used to manipulate them. The remaining methods are classified 067 * as operations and returned by {@link getOperations()}. 068 * </p> 069 * <p> 070 * Beans can also broadcast notifications. If the bean provides this 071 * facility, by implementing the {@link NotificationBroadcaster} 072 * interface, then an array of {@link MBeanNotificationInfo} objects 073 * may be obtained from {@link #getNotifications()}, which describe 074 * the notifications emitted. 075 * </p> 076 * <p> 077 * Model management beans and open management beans also supply an 078 * instance of this class, as part of implementing the 079 * {@link DynamicMBean#getMBeanInfo()} method of {@link DynamicMBean}. 080 * </p> 081 * 082 * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 083 * @since 1.5 084 */ 085public class MBeanInfo 086 implements Cloneable, Serializable 087{ 088 089 /** 090 * Compatible with JDK 1.5 091 */ 092 private static final long serialVersionUID = -6451021435135161911L; 093 094 /** 095 * A description of the bean. 096 * 097 * @serial The bean's description. 098 */ 099 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}