View Javadoc

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 }