001 /* MBeanInfo.java -- Information about a management bean.
002 Copyright (C) 2006 Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038 package javax.management;
039
040 import java.io.Serializable;
041
042 import 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 */
085 public 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 }