001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.commons.modeler;
019:
020: import java.util.ArrayList;
021: import java.util.Iterator;
022: import java.util.List;
023:
024: import javax.management.Descriptor;
025: import javax.management.InstanceNotFoundException;
026: import javax.management.MBeanException;
027: import javax.management.RuntimeOperationsException;
028: import javax.management.modelmbean.InvalidTargetObjectTypeException;
029: import javax.management.modelmbean.ModelMBean;
030: import javax.management.modelmbean.ModelMBeanAttributeInfo;
031: import javax.management.modelmbean.ModelMBeanConstructorInfo;
032: import javax.management.modelmbean.ModelMBeanInfo;
033: import javax.management.modelmbean.ModelMBeanInfoSupport;
034: import javax.management.modelmbean.ModelMBeanNotificationInfo;
035: import javax.management.modelmbean.ModelMBeanOperationInfo;
036:
037: /**
038: * <p>Internal configuration information for a managed bean (MBean)
039: * descriptor.</p>
040: *
041: * @author Craig R. McClanahan
042: * @version $Revision: 480402 $ $Date: 2006-11-29 04:43:23 +0000 (Wed, 29 Nov 2006) $
043: */
044:
045: public class ManagedBean implements java.io.Serializable {
046: // ----------------------------------------------------- Instance Variables
047:
048: /**
049: * The <code>ModelMBeanInfo</code> object that corresponds
050: * to this <code>ManagedBean</code> instance.
051: */
052: transient ModelMBeanInfo info = null;
053: protected AttributeInfo attributes[] = new AttributeInfo[0];
054: protected String className = "org.apache.commons.modeler.BaseModelMBean";
055: protected ConstructorInfo constructors[] = new ConstructorInfo[0];
056: protected String description = null;
057: protected String domain = null;
058: protected String group = null;
059: protected String name = null;
060:
061: protected List fields = new ArrayList();
062: protected NotificationInfo notifications[] = new NotificationInfo[0];
063: protected OperationInfo operations[] = new OperationInfo[0];
064: protected String type = null;
065:
066: /** Constructor. Will add default attributes.
067: *
068: */
069: public ManagedBean() {
070: AttributeInfo ai = new AttributeInfo();
071: ai.setName("modelerType");
072: ai
073: .setDescription("Type of the modeled resource. Can be set only once");
074: ai.setType("java.lang.String");
075: ai.setWriteable(false);
076: addAttribute(ai);
077: }
078:
079: // ------------------------------------------------------------- Properties
080:
081: /**
082: * The collection of attributes for this MBean.
083: */
084: public AttributeInfo[] getAttributes() {
085: return (this .attributes);
086: }
087:
088: /**
089: * The fully qualified name of the Java class of the MBean
090: * described by this descriptor. If not specified, the standard JMX
091: * class (<code>javax.management.modelmbean.RequiredModeLMBean</code>)
092: * will be utilized.
093: */
094: public String getClassName() {
095: return (this .className);
096: }
097:
098: public void setClassName(String className) {
099: this .className = className;
100: this .info = null;
101: }
102:
103: /**
104: * The collection of constructors for this MBean.
105: */
106: public ConstructorInfo[] getConstructors() {
107: return (this .constructors);
108: }
109:
110: /**
111: * The human-readable description of this MBean.
112: */
113: public String getDescription() {
114: return (this .description);
115: }
116:
117: public void setDescription(String description) {
118: this .description = description;
119: this .info = null;
120: }
121:
122: /**
123: * The (optional) <code>ObjectName</code> domain in which this MBean
124: * should be registered in the MBeanServer.
125: */
126: public String getDomain() {
127: return (this .domain);
128: }
129:
130: public void setDomain(String domain) {
131: this .domain = domain;
132: }
133:
134: /**
135: * <p>Return a <code>List</code> of the {@link FieldInfo} objects for
136: * the name/value pairs that should be
137: * added to the Descriptor created from this metadata.</p>
138: */
139: public List getFields() {
140: return (this .fields);
141: }
142:
143: /**
144: * The (optional) group to which this MBean belongs.
145: */
146: public String getGroup() {
147: return (this .group);
148: }
149:
150: public void setGroup(String group) {
151: this .group = group;
152: }
153:
154: /**
155: * The name of this managed bean, which must be unique among all
156: * MBeans managed by a particular MBeans server.
157: */
158: public String getName() {
159: return (this .name);
160: }
161:
162: public void setName(String name) {
163: this .name = name;
164: this .info = null;
165: }
166:
167: /**
168: * The collection of notifications for this MBean.
169: */
170: public NotificationInfo[] getNotifications() {
171: return (this .notifications);
172: }
173:
174: /**
175: * The collection of operations for this MBean.
176: */
177: public OperationInfo[] getOperations() {
178: return (this .operations);
179: }
180:
181: /**
182: * The fully qualified name of the Java class of the resource
183: * implementation class described by the managed bean described
184: * by this descriptor.
185: */
186: public String getType() {
187: return (this .type);
188: }
189:
190: public void setType(String type) {
191: this .type = type;
192: this .info = null;
193: }
194:
195: // --------------------------------------------------------- Public Methods
196:
197: /**
198: * Add a new attribute to the set of attributes for this MBean.
199: *
200: * @param attribute The new attribute descriptor
201: */
202: public void addAttribute(AttributeInfo attribute) {
203:
204: synchronized (attributes) {
205: AttributeInfo results[] = new AttributeInfo[attributes.length + 1];
206: System.arraycopy(attributes, 0, results, 0,
207: attributes.length);
208: results[attributes.length] = attribute;
209: attributes = results;
210: this .info = null;
211: }
212:
213: }
214:
215: /**
216: * Add a new constructor to the set of constructors for this MBean.
217: *
218: * @param constructor The new constructor descriptor
219: */
220: public void addConstructor(ConstructorInfo constructor) {
221:
222: synchronized (constructors) {
223: ConstructorInfo results[] = new ConstructorInfo[constructors.length + 1];
224: System.arraycopy(constructors, 0, results, 0,
225: constructors.length);
226: results[constructors.length] = constructor;
227: constructors = results;
228: this .info = null;
229: }
230:
231: }
232:
233: /**
234: * <p>Add a new field to the fields associated with the
235: * Descriptor that will be created from this metadata.</p>
236: *
237: * @param field The field to be added
238: */
239: public void addField(FieldInfo field) {
240: fields.add(field);
241: }
242:
243: /**
244: * Add a new notification to the set of notifications for this MBean.
245: *
246: * @param notification The new notification descriptor
247: */
248: public void addNotification(NotificationInfo notification) {
249:
250: synchronized (notifications) {
251: NotificationInfo results[] = new NotificationInfo[notifications.length + 1];
252: System.arraycopy(notifications, 0, results, 0,
253: notifications.length);
254: results[notifications.length] = notification;
255: notifications = results;
256: this .info = null;
257: }
258:
259: }
260:
261: /**
262: * Add a new operation to the set of operations for this MBean.
263: *
264: * @param operation The new operation descriptor
265: */
266: public void addOperation(OperationInfo operation) {
267: synchronized (operations) {
268: OperationInfo results[] = new OperationInfo[operations.length + 1];
269: System.arraycopy(operations, 0, results, 0,
270: operations.length);
271: results[operations.length] = operation;
272: operations = results;
273: this .info = null;
274: }
275:
276: }
277:
278: /**
279: * Create and return a <code>ModelMBean</code> that has been
280: * preconfigured with the <code>ModelMBeanInfo</code> information
281: * for this managed bean, but is not associated with any particular
282: * managed resource. The returned <code>ModelMBean</code> will
283: * <strong>NOT</strong> have been registered with our
284: * <code>MBeanServer</code>.
285: *
286: * @exception InstanceNotFoundException if the managed resource
287: * object cannot be found
288: * @exception InvalidTargetObjectTypeException if our MBean cannot
289: * handle object references (should never happen)
290: * @exception MBeanException if a problem occurs instantiating the
291: * <code>ModelMBean</code> instance
292: * @exception RuntimeOperationsException if a JMX runtime error occurs
293: */
294: public ModelMBean createMBean() throws InstanceNotFoundException,
295: InvalidTargetObjectTypeException, MBeanException,
296: RuntimeOperationsException {
297:
298: return (createMBean(null));
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, and is associated with the specified
306: * managed object instance. The returned <code>ModelMBean</code>
307: * will <strong>NOT</strong> have been registered with our
308: * <code>MBeanServer</code>.
309: *
310: * @param instance Instanced of the managed object, or <code>null</code>
311: * for no associated instance
312: *
313: * @exception InstanceNotFoundException if the managed resource
314: * object cannot be found
315: * @exception InvalidTargetObjectTypeException if our MBean cannot
316: * handle object references (should never happen)
317: * @exception MBeanException if a problem occurs instantiating the
318: * <code>ModelMBean</code> instance
319: * @exception RuntimeOperationsException if a JMX runtime error occurs
320: */
321: public ModelMBean createMBean(Object instance)
322: throws InstanceNotFoundException,
323: InvalidTargetObjectTypeException, MBeanException,
324: RuntimeOperationsException {
325:
326: // Load the ModelMBean implementation class
327: Class clazz = null;
328: Exception ex = null;
329: try {
330: clazz = Class.forName(getClassName());
331: } catch (Exception e) {
332: }
333:
334: if (clazz == null) {
335: try {
336: ClassLoader cl = Thread.currentThread()
337: .getContextClassLoader();
338: if (cl != null)
339: clazz = cl.loadClass(getClassName());
340: } catch (Exception e) {
341: ex = e;
342: }
343: }
344:
345: if (clazz == null) {
346: throw new MBeanException(ex,
347: "Cannot load ModelMBean class " + getClassName());
348: }
349:
350: // Create a new ModelMBean instance
351: ModelMBean mbean = null;
352: try {
353: mbean = (ModelMBean) clazz.newInstance();
354: mbean.setModelMBeanInfo(createMBeanInfo());
355: } catch (MBeanException e) {
356: throw e;
357: } catch (RuntimeOperationsException e) {
358: throw e;
359: } catch (Exception e) {
360: throw new MBeanException(e,
361: "Cannot instantiate ModelMBean of class "
362: + getClassName());
363: }
364:
365: // Set the managed resource (if any)
366: try {
367: if (instance != null)
368: mbean.setManagedResource(instance, "ObjectReference");
369: } catch (InstanceNotFoundException e) {
370: throw e;
371: } catch (InvalidTargetObjectTypeException e) {
372: throw e;
373: }
374: return (mbean);
375:
376: }
377:
378: /**
379: * Create and return a <code>ModelMBeanInfo</code> object that
380: * describes this entire managed bean.
381: */
382: public ModelMBeanInfo createMBeanInfo() {
383:
384: // Return our cached information (if any)
385: if (info != null)
386: return (info);
387:
388: // Create subordinate information descriptors as required
389: AttributeInfo attrs[] = getAttributes();
390: ModelMBeanAttributeInfo attributes[] = new ModelMBeanAttributeInfo[attrs.length];
391: for (int i = 0; i < attrs.length; i++)
392: attributes[i] = attrs[i].createAttributeInfo();
393:
394: ConstructorInfo consts[] = getConstructors();
395: ModelMBeanConstructorInfo constructors[] = new ModelMBeanConstructorInfo[consts.length];
396: for (int i = 0; i < consts.length; i++)
397: constructors[i] = consts[i].createConstructorInfo();
398: NotificationInfo notifs[] = getNotifications();
399: ModelMBeanNotificationInfo notifications[] = new ModelMBeanNotificationInfo[notifs.length];
400: for (int i = 0; i < notifs.length; i++)
401: notifications[i] = notifs[i].createNotificationInfo();
402: OperationInfo opers[] = getOperations();
403: ModelMBeanOperationInfo operations[] = new ModelMBeanOperationInfo[opers.length];
404: for (int i = 0; i < opers.length; i++)
405: operations[i] = opers[i].createOperationInfo();
406:
407: /*
408: // Add operations for attribute getters and setters as needed
409: ArrayList list = new ArrayList();
410: for (int i = 0; i < operations.length; i++)
411: list.add(operations[i]);
412: for (int i = 0; i < attributes.length; i++) {
413: Descriptor descriptor = attributes[i].getDescriptor();
414: String getMethod = (String) descriptor.getFieldValue("getMethod");
415: if (getMethod != null) {
416: OperationInfo oper =
417: new OperationInfo(getMethod, true,
418: attributes[i].getType());
419: list.add(oper.createOperationInfo());
420: }
421: String setMethod = (String) descriptor.getFieldValue("setMethod");
422: if (setMethod != null) {
423: OperationInfo oper =
424: new OperationInfo(setMethod, false,
425: attributes[i].getType());
426: list.add(oper.createOperationInfo());
427: }
428: }
429: if (list.size() > operations.length)
430: operations =
431: (ModelMBeanOperationInfo[]) list.toArray(operations);
432: */
433:
434: // Construct and return a new ModelMBeanInfo object
435: info = new ModelMBeanInfoSupport(getClassName(),
436: getDescription(), attributes, constructors, operations,
437: notifications);
438: try {
439: Descriptor descriptor = info.getMBeanDescriptor();
440: Iterator fields = getFields().iterator();
441: while (fields.hasNext()) {
442: FieldInfo field = (FieldInfo) fields.next();
443: descriptor.setField(field.getName(), field.getValue());
444: }
445: info.setMBeanDescriptor(descriptor);
446: } catch (MBeanException e) {
447: ;
448: }
449:
450: return (info);
451:
452: }
453:
454: /**
455: * Return a string representation of this managed bean.
456: */
457: public String toString() {
458:
459: StringBuffer sb = new StringBuffer("ManagedBean[");
460: sb.append("name=");
461: sb.append(name);
462: sb.append(", className=");
463: sb.append(className);
464: sb.append(", description=");
465: sb.append(description);
466: if (group != null) {
467: sb.append(", group=");
468: sb.append(group);
469: }
470: sb.append(", type=");
471: sb.append(type);
472: sb.append("]");
473: return (sb.toString());
474:
475: }
476:
477: }
|