1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19 package org.apache.commons.modeler;
20
21
22 import java.util.ArrayList;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import javax.management.Descriptor;
27 import javax.management.InstanceNotFoundException;
28 import javax.management.MBeanException;
29 import javax.management.RuntimeOperationsException;
30 import javax.management.modelmbean.InvalidTargetObjectTypeException;
31 import javax.management.modelmbean.ModelMBean;
32 import javax.management.modelmbean.ModelMBeanAttributeInfo;
33 import javax.management.modelmbean.ModelMBeanConstructorInfo;
34 import javax.management.modelmbean.ModelMBeanInfo;
35 import javax.management.modelmbean.ModelMBeanInfoSupport;
36 import javax.management.modelmbean.ModelMBeanNotificationInfo;
37 import javax.management.modelmbean.ModelMBeanOperationInfo;
38
39
40 /**
41 * <p>Internal configuration information for a managed bean (MBean)
42 * descriptor.</p>
43 *
44 * @author Craig R. McClanahan
45 * @version $Revision: 480402 $ $Date: 2006-11-29 04:43:23 +0000 (Wed, 29 Nov 2006) $
46 */
47
48 public class ManagedBean implements java.io.Serializable
49 {
50 // ----------------------------------------------------- Instance Variables
51
52
53 /**
54 * The <code>ModelMBeanInfo</code> object that corresponds
55 * to this <code>ManagedBean</code> instance.
56 */
57 transient ModelMBeanInfo info = null;
58 protected AttributeInfo attributes[] = new AttributeInfo[0];
59 protected String className =
60 "org.apache.commons.modeler.BaseModelMBean";
61 protected ConstructorInfo constructors[] = new ConstructorInfo[0];
62 protected String description = null;
63 protected String domain = null;
64 protected String group = null;
65 protected String name = null;
66
67 protected List fields = new ArrayList();
68 protected NotificationInfo notifications[] = new NotificationInfo[0];
69 protected OperationInfo operations[] = new OperationInfo[0];
70 protected String type = null;
71
72 /** Constructor. Will add default attributes.
73 *
74 */
75 public ManagedBean() {
76 AttributeInfo ai=new AttributeInfo();
77 ai.setName("modelerType");
78 ai.setDescription("Type of the modeled resource. Can be set only once");
79 ai.setType("java.lang.String");
80 ai.setWriteable(false);
81 addAttribute(ai);
82 }
83
84 // ------------------------------------------------------------- Properties
85
86
87 /**
88 * The collection of attributes for this MBean.
89 */
90 public AttributeInfo[] getAttributes() {
91 return (this.attributes);
92 }
93
94
95 /**
96 * The fully qualified name of the Java class of the MBean
97 * described by this descriptor. If not specified, the standard JMX
98 * class (<code>javax.management.modelmbean.RequiredModeLMBean</code>)
99 * will be utilized.
100 */
101 public String getClassName() {
102 return (this.className);
103 }
104
105 public void setClassName(String className) {
106 this.className = className;
107 this.info = null;
108 }
109
110
111 /**
112 * The collection of constructors for this MBean.
113 */
114 public ConstructorInfo[] getConstructors() {
115 return (this.constructors);
116 }
117
118
119 /**
120 * The human-readable description of this MBean.
121 */
122 public String getDescription() {
123 return (this.description);
124 }
125
126 public void setDescription(String description) {
127 this.description = description;
128 this.info = null;
129 }
130
131
132 /**
133 * The (optional) <code>ObjectName</code> domain in which this MBean
134 * should be registered in the MBeanServer.
135 */
136 public String getDomain() {
137 return (this.domain);
138 }
139
140 public void setDomain(String domain) {
141 this.domain = domain;
142 }
143
144
145 /**
146 * <p>Return a <code>List</code> of the {@link FieldInfo} objects for
147 * the name/value pairs that should be
148 * added to the Descriptor created from this metadata.</p>
149 */
150 public List getFields() {
151 return (this.fields);
152 }
153
154
155 /**
156 * The (optional) group to which this MBean belongs.
157 */
158 public String getGroup() {
159 return (this.group);
160 }
161
162 public void setGroup(String group) {
163 this.group = group;
164 }
165
166
167 /**
168 * The name of this managed bean, which must be unique among all
169 * MBeans managed by a particular MBeans server.
170 */
171 public String getName() {
172 return (this.name);
173 }
174
175 public void setName(String name) {
176 this.name = name;
177 this.info = null;
178 }
179
180
181 /**
182 * The collection of notifications for this MBean.
183 */
184 public NotificationInfo[] getNotifications() {
185 return (this.notifications);
186 }
187
188
189 /**
190 * The collection of operations for this MBean.
191 */
192 public OperationInfo[] getOperations() {
193 return (this.operations);
194 }
195
196
197 /**
198 * The fully qualified name of the Java class of the resource
199 * implementation class described by the managed bean described
200 * by this descriptor.
201 */
202 public String getType() {
203 return (this.type);
204 }
205
206 public void setType(String type) {
207 this.type = type;
208 this.info = null;
209 }
210
211
212 // --------------------------------------------------------- Public Methods
213
214
215 /**
216 * Add a new attribute to the set of attributes for this MBean.
217 *
218 * @param attribute The new attribute descriptor
219 */
220 public void addAttribute(AttributeInfo attribute) {
221
222 synchronized (attributes) {
223 AttributeInfo results[] =
224 new AttributeInfo[attributes.length + 1];
225 System.arraycopy(attributes, 0, results, 0, attributes.length);
226 results[attributes.length] = attribute;
227 attributes = results;
228 this.info = null;
229 }
230
231 }
232
233
234 /**
235 * Add a new constructor to the set of constructors for this MBean.
236 *
237 * @param constructor The new constructor descriptor
238 */
239 public void addConstructor(ConstructorInfo constructor) {
240
241 synchronized (constructors) {
242 ConstructorInfo results[] =
243 new ConstructorInfo[constructors.length + 1];
244 System.arraycopy(constructors, 0, results, 0, constructors.length);
245 results[constructors.length] = constructor;
246 constructors = results;
247 this.info = null;
248 }
249
250 }
251
252
253 /**
254 * <p>Add a new field to the fields associated with the
255 * Descriptor that will be created from this metadata.</p>
256 *
257 * @param field The field to be added
258 */
259 public void addField(FieldInfo field) {
260 fields.add(field);
261 }
262
263
264 /**
265 * Add a new notification to the set of notifications for this MBean.
266 *
267 * @param notification The new notification descriptor
268 */
269 public void addNotification(NotificationInfo notification) {
270
271 synchronized (notifications) {
272 NotificationInfo results[] =
273 new NotificationInfo[notifications.length + 1];
274 System.arraycopy(notifications, 0, results, 0,
275 notifications.length);
276 results[notifications.length] = notification;
277 notifications = results;
278 this.info = null;
279 }
280
281 }
282
283
284 /**
285 * Add a new operation to the set of operations for this MBean.
286 *
287 * @param operation The new operation descriptor
288 */
289 public void addOperation(OperationInfo operation) {
290 synchronized (operations) {
291 OperationInfo results[] =
292 new OperationInfo[operations.length + 1];
293 System.arraycopy(operations, 0, results, 0, operations.length);
294 results[operations.length] = operation;
295 operations = results;
296 this.info = null;
297 }
298
299 }
300
301
302 /**
303 * Create and return a <code>ModelMBean</code> that has been
304 * preconfigured with the <code>ModelMBeanInfo</code> information
305 * for this managed bean, but is not associated with any particular
306 * managed resource. The returned <code>ModelMBean</code> will
307 * <strong>NOT</strong> have been registered with our
308 * <code>MBeanServer</code>.
309 *
310 * @exception InstanceNotFoundException if the managed resource
311 * object cannot be found
312 * @exception InvalidTargetObjectTypeException if our MBean cannot
313 * handle object references (should never happen)
314 * @exception MBeanException if a problem occurs instantiating the
315 * <code>ModelMBean</code> instance
316 * @exception RuntimeOperationsException if a JMX runtime error occurs
317 */
318 public ModelMBean createMBean()
319 throws InstanceNotFoundException,
320 InvalidTargetObjectTypeException,
321 MBeanException, RuntimeOperationsException {
322
323 return (createMBean(null));
324
325 }
326
327
328 /**
329 * Create and return a <code>ModelMBean</code> that has been
330 * preconfigured with the <code>ModelMBeanInfo</code> information
331 * for this managed bean, and is associated with the specified
332 * managed object instance. The returned <code>ModelMBean</code>
333 * will <strong>NOT</strong> have been registered with our
334 * <code>MBeanServer</code>.
335 *
336 * @param instance Instanced of the managed object, or <code>null</code>
337 * for no associated instance
338 *
339 * @exception InstanceNotFoundException if the managed resource
340 * object cannot be found
341 * @exception InvalidTargetObjectTypeException if our MBean cannot
342 * handle object references (should never happen)
343 * @exception MBeanException if a problem occurs instantiating the
344 * <code>ModelMBean</code> instance
345 * @exception RuntimeOperationsException if a JMX runtime error occurs
346 */
347 public ModelMBean createMBean(Object instance)
348 throws InstanceNotFoundException,
349 InvalidTargetObjectTypeException,
350 MBeanException, RuntimeOperationsException {
351
352 // Load the ModelMBean implementation class
353 Class clazz = null;
354 Exception ex = null;
355 try {
356 clazz = Class.forName(getClassName());
357 } catch (Exception e) {
358 }
359
360 if( clazz==null ) {
361 try {
362 ClassLoader cl= Thread.currentThread().getContextClassLoader();
363 if ( cl != null)
364 clazz= cl.loadClass(getClassName());
365 } catch (Exception e) {
366 ex=e;
367 }
368 }
369
370 if( clazz==null) {
371 throw new MBeanException
372 (ex, "Cannot load ModelMBean class " + getClassName());
373 }
374
375 // Create a new ModelMBean instance
376 ModelMBean mbean = null;
377 try {
378 mbean = (ModelMBean) clazz.newInstance();
379 mbean.setModelMBeanInfo(createMBeanInfo());
380 } catch (MBeanException e) {
381 throw e;
382 } catch (RuntimeOperationsException e) {
383 throw e;
384 } catch (Exception e) {
385 throw new MBeanException
386 (e, "Cannot instantiate ModelMBean of class " +
387 getClassName());
388 }
389
390 // Set the managed resource (if any)
391 try {
392 if (instance != null)
393 mbean.setManagedResource(instance, "ObjectReference");
394 } catch (InstanceNotFoundException e) {
395 throw e;
396 } catch (InvalidTargetObjectTypeException e) {
397 throw e;
398 }
399 return (mbean);
400
401 }
402
403
404 /**
405 * Create and return a <code>ModelMBeanInfo</code> object that
406 * describes this entire managed bean.
407 */
408 public ModelMBeanInfo createMBeanInfo() {
409
410 // Return our cached information (if any)
411 if (info != null)
412 return (info);
413
414 // Create subordinate information descriptors as required
415 AttributeInfo attrs[] = getAttributes();
416 ModelMBeanAttributeInfo attributes[] =
417 new ModelMBeanAttributeInfo[attrs.length];
418 for (int i = 0; i < attrs.length; i++)
419 attributes[i] = attrs[i].createAttributeInfo();
420
421 ConstructorInfo consts[] = getConstructors();
422 ModelMBeanConstructorInfo constructors[] =
423 new ModelMBeanConstructorInfo[consts.length];
424 for (int i = 0; i < consts.length; i++)
425 constructors[i] = consts[i].createConstructorInfo();
426 NotificationInfo notifs[] = getNotifications();
427 ModelMBeanNotificationInfo notifications[] =
428 new ModelMBeanNotificationInfo[notifs.length];
429 for (int i = 0; i < notifs.length; i++)
430 notifications[i] = notifs[i].createNotificationInfo();
431 OperationInfo opers[] = getOperations();
432 ModelMBeanOperationInfo operations[] =
433 new ModelMBeanOperationInfo[opers.length];
434 for (int i = 0; i < opers.length; i++)
435 operations[i] = opers[i].createOperationInfo();
436
437 /*
438 // Add operations for attribute getters and setters as needed
439 ArrayList list = new ArrayList();
440 for (int i = 0; i < operations.length; i++)
441 list.add(operations[i]);
442 for (int i = 0; i < attributes.length; i++) {
443 Descriptor descriptor = attributes[i].getDescriptor();
444 String getMethod = (String) descriptor.getFieldValue("getMethod");
445 if (getMethod != null) {
446 OperationInfo oper =
447 new OperationInfo(getMethod, true,
448 attributes[i].getType());
449 list.add(oper.createOperationInfo());
450 }
451 String setMethod = (String) descriptor.getFieldValue("setMethod");
452 if (setMethod != null) {
453 OperationInfo oper =
454 new OperationInfo(setMethod, false,
455 attributes[i].getType());
456 list.add(oper.createOperationInfo());
457 }
458 }
459 if (list.size() > operations.length)
460 operations =
461 (ModelMBeanOperationInfo[]) list.toArray(operations);
462 */
463
464 // Construct and return a new ModelMBeanInfo object
465 info = new ModelMBeanInfoSupport
466 (getClassName(), getDescription(),
467 attributes, constructors, operations, notifications);
468 try {
469 Descriptor descriptor = info.getMBeanDescriptor();
470 Iterator fields = getFields().iterator();
471 while (fields.hasNext()) {
472 FieldInfo field = (FieldInfo) fields.next();
473 descriptor.setField(field.getName(), field.getValue());
474 }
475 info.setMBeanDescriptor(descriptor);
476 } catch (MBeanException e) {
477 ;
478 }
479
480 return (info);
481
482 }
483
484
485 /**
486 * Return a string representation of this managed bean.
487 */
488 public String toString() {
489
490 StringBuffer sb = new StringBuffer("ManagedBean[");
491 sb.append("name=");
492 sb.append(name);
493 sb.append(", className=");
494 sb.append(className);
495 sb.append(", description=");
496 sb.append(description);
497 if (group != null) {
498 sb.append(", group=");
499 sb.append(group);
500 }
501 sb.append(", type=");
502 sb.append(type);
503 sb.append("]");
504 return (sb.toString());
505
506 }
507
508
509 }