View Javadoc

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