KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > util > jmx > ModelMBeanImpl


1 // ========================================================================
2
// $Id: ModelMBeanImpl.java,v 1.18 2005/08/13 00:01:28 gregwilkins Exp $
3
// Copyright 1999-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.util.jmx;
17
18 import java.lang.reflect.InvocationTargetException JavaDoc;
19 import java.lang.reflect.Method JavaDoc;
20 import java.lang.reflect.Modifier JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.Iterator JavaDoc;
24 import java.util.Locale JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.ResourceBundle JavaDoc;
27
28 import javax.management.Attribute JavaDoc;
29 import javax.management.AttributeChangeNotification JavaDoc;
30 import javax.management.AttributeList JavaDoc;
31 import javax.management.AttributeNotFoundException JavaDoc;
32 import javax.management.InstanceNotFoundException JavaDoc;
33 import javax.management.InvalidAttributeValueException JavaDoc;
34 import javax.management.ListenerNotFoundException JavaDoc;
35 import javax.management.MBeanException JavaDoc;
36 import javax.management.MBeanInfo JavaDoc;
37 import javax.management.MBeanNotificationInfo JavaDoc;
38 import javax.management.MBeanOperationInfo JavaDoc;
39 import javax.management.MBeanParameterInfo JavaDoc;
40 import javax.management.MBeanRegistration JavaDoc;
41 import javax.management.MBeanServer JavaDoc;
42 import javax.management.Notification JavaDoc;
43 import javax.management.NotificationFilter JavaDoc;
44 import javax.management.NotificationListener JavaDoc;
45 import javax.management.ObjectName JavaDoc;
46 import javax.management.ReflectionException JavaDoc;
47 import javax.management.RuntimeOperationsException JavaDoc;
48 import javax.management.modelmbean.InvalidTargetObjectTypeException JavaDoc;
49 import javax.management.modelmbean.ModelMBean JavaDoc;
50 import javax.management.modelmbean.ModelMBeanAttributeInfo JavaDoc;
51 import javax.management.modelmbean.ModelMBeanInfo JavaDoc;
52 import javax.management.modelmbean.ModelMBeanInfoSupport JavaDoc;
53 import javax.management.modelmbean.ModelMBeanNotificationInfo JavaDoc;
54 import javax.management.modelmbean.ModelMBeanOperationInfo JavaDoc;
55
56 import org.apache.commons.logging.Log;
57 import org.mortbay.log.LogFactory;
58 import org.mortbay.util.LogSupport;
59 import org.mortbay.util.TypeUtil;
60
61
62 /* ------------------------------------------------------------ */
63 /** Model MBean Implementation.
64  * This implementation of the JMX Model MBean API is designed to allow
65  * easy creation of Model MBeans. From minimal descriptions of
66  * operations and attributes, reflection is used to determine the full
67  * signature and ResourceBundles are used to determine other meta data.
68  *
69  * This class is normally used in one of the following patterns:<UL>
70  * <LI>As a base class for a real MBean that contains the actual
71  * attributes and operations of the MBean. Such an Object is only
72  * usable in a JMX environment.
73  * <LI>As a proxy MBean to another non-JMX object. The attributes and
74  * operations of the proxied object are defined in the MBean. This
75  * pattern is used when an existing non-JMX objects API is to be
76  * exposed as an MBean.
77  * <LI>As a base class for a proxy MBean. The attributes and oepration
78  * of the MBean are implemented by the derived class but delegate to
79  * one or more other objects. This pattern is used if existing objects
80  * are to be managed by JMX, but a new management API needs to be
81  * defined.
82  * </UL>
83  *
84  * @version $Revision: 1.18 $
85  * @author Greg Wilkins (gregw)
86  */

87 public class ModelMBeanImpl
88     implements ModelMBean JavaDoc,
89                MBeanRegistration JavaDoc
90 {
91     private static Log log = LogFactory.getLog(ModelMBeanImpl.class);
92
93     public final static int IMPACT_ACTION = MBeanOperationInfo.ACTION;
94     public final static int IMPACT_ACTION_INFO = MBeanOperationInfo.ACTION_INFO;
95     public final static int IMPACT_INFO = MBeanOperationInfo.INFO;
96     public final static int IMPACT_UNKOWN = MBeanOperationInfo.UNKNOWN;
97
98     public final static String JavaDoc STRING="java.lang.String";
99     public final static String JavaDoc OBJECT="java.lang.Object";
100     public final static String JavaDoc INT="int";
101     
102     public final static String JavaDoc[] NO_PARAMS=new String JavaDoc[0];
103
104     public final static boolean READ_WRITE=true;
105     public final static boolean READ_ONLY=false;
106     public final static boolean ON_MBEAN=true;
107     public final static boolean ON_OBJECT=false;
108     
109     
110     private static HashMap JavaDoc __objectId = new HashMap JavaDoc();
111
112     private static String JavaDoc __defaultDomain="org.mortbay";
113     
114     protected ModelMBeanInfoSupport JavaDoc _beanInfo;
115     private MBeanServer JavaDoc _mBeanServer;
116     private Object JavaDoc _object;
117     private ObjectName JavaDoc _objectName;
118     
119     private boolean _dirty=false;
120     private HashMap JavaDoc _getter = new HashMap JavaDoc(4);
121     private HashMap JavaDoc _setter = new HashMap JavaDoc(4);
122     private HashMap JavaDoc _method = new HashMap JavaDoc(4);
123     private ArrayList JavaDoc _attributes = new ArrayList JavaDoc(4);
124     private ArrayList JavaDoc _operations = new ArrayList JavaDoc(4);
125     private ArrayList JavaDoc _notifications = new ArrayList JavaDoc(4);
126     private String JavaDoc _baseObjectName=null;
127     private Map JavaDoc _components = new HashMap JavaDoc(4);
128
129     /* ------------------------------------------------------------ */
130     /* ------------------------------------------------------------ */
131     /** Create MBean for Object.
132      * Attempts to create an MBean for the object by searching the
133      * package and class name space. For example an object of the
134      * type <PRE>
135      * class com.acme.MyClass extends com.acme.util.BaseClass
136      * </PRE>
137      * Then this method would look for the following
138      * classes:<UL>
139      * <LI>com.acme.MyClassMBean
140      * <LI>com.acme.jmx.MyClassMBean
141      * <LI>com.acme.util.BaseClassMBean
142      * <LI>com.acme.util.jmx.BaseClassMBean
143      * </UL>
144      * @param o The object
145      * @return A new instance of an MBean for the object or null.
146      */

147     public static ModelMBean JavaDoc mbeanFor(Object JavaDoc o)
148     {
149         try
150         {
151             Class JavaDoc oClass = o.getClass();
152             ClassLoader JavaDoc loader =oClass.getClassLoader();
153
154             ModelMBean JavaDoc mbean = null;
155             boolean jmx=false;
156             Class JavaDoc[] interfaces=null;
157             int i=0;
158             
159             while (mbean==null && oClass!=null)
160             {
161                 Class JavaDoc focus=interfaces==null?oClass:interfaces[i];
162                 String JavaDoc pName = focus.getPackage().getName();
163                 String JavaDoc cName = focus.getName().substring(pName.length()+1);
164                 String JavaDoc mName=pName+(jmx?".jmx.":".")+cName+"MBean";
165
166                 try{
167                     Class JavaDoc mClass=loader.loadClass(mName);
168             if(log.isTraceEnabled())log.trace("mbeanFor "+o+" mClass="+mClass);
169                     mbean=(ModelMBean JavaDoc)mClass.newInstance();
170                     mbean.setManagedResource(o,"objectReference");
171             if(log.isDebugEnabled())log.debug("mbeanFor "+o+" is "+mbean);
172                     return mbean;
173                 }
174                 catch(ClassNotFoundException JavaDoc e)
175                 {
176                     if (e.toString().endsWith("MBean"))
177             { if(log.isTraceEnabled())log.trace(e.toString());}
178                     else
179                         log.warn(LogSupport.EXCEPTION,e);
180                 }
181                 catch(Error JavaDoc e)
182                 {
183                     log.warn(LogSupport.EXCEPTION,e);
184                     mbean=null;
185                 }
186                 catch(Exception JavaDoc e)
187                 {
188                     log.warn(LogSupport.EXCEPTION,e);
189                     mbean=null;
190                 }
191
192                 if (jmx)
193                 {
194                     if (interfaces!=null)
195                     {
196                         i++;
197                         if (i>=interfaces.length)
198                         {
199                             interfaces=null;
200                             oClass=oClass.getSuperclass();
201                         }
202                     }
203                     else
204                     {
205                         interfaces=oClass.getInterfaces();
206                         i=0;
207                         if (interfaces==null || interfaces.length==0)
208                         {
209                             interfaces=null;
210                             oClass=oClass.getSuperclass();
211                         }
212                     }
213                 }
214                 jmx=!jmx;
215             }
216         }
217         catch(Exception JavaDoc e)
218         {
219             LogSupport.ignore(log,e);
220         }
221         return null;
222     }
223     
224     /* ------------------------------------------------------------ */
225     /** MBean Constructor.
226      * No proxy object is defined. Attributes and operations are
227      * defined on this instance.
228      */

229     public ModelMBeanImpl()
230     {}
231     
232     /* ------------------------------------------------------------ */
233     /** Proxy MBean Constructor.
234      * @param proxyObject The actual object on which attributes and
235      * operations are to be defined and called.
236      */

237     public ModelMBeanImpl(Object JavaDoc proxyObject)
238     {
239         try
240         {
241             setManagedResource(proxyObject,"objectReference");
242         }
243         catch(Exception JavaDoc e)
244         {
245             log.warn(LogSupport.EXCEPTION,e);
246             throw new IllegalArgumentException JavaDoc(e.toString());
247         }
248     }
249     
250     
251     /* ------------------------------------------------------------ */
252     public static String JavaDoc getDefaultDomain() { return __defaultDomain; }
253     
254     /* ------------------------------------------------------------ */
255     public static void setDefaultDomain(String JavaDoc d) { __defaultDomain=d; }
256     
257     /* ------------------------------------------------------------ */
258     public MBeanServer JavaDoc getMBeanServer() { return _mBeanServer; }
259
260     /* ------------------------------------------------------------ */
261     public ObjectName JavaDoc getObjectName() { return _objectName; }
262     
263     /* ------------------------------------------------------------ */
264     public Object JavaDoc getManagedResource() { return _object; }
265   
266     /* ------------------------------------------------------------ */
267     public void setManagedResource(Object JavaDoc proxyObject, String JavaDoc type)
268         throws MBeanException JavaDoc,
269                RuntimeOperationsException JavaDoc,
270                InstanceNotFoundException JavaDoc,
271                InvalidTargetObjectTypeException JavaDoc
272     {
273         if (proxyObject==null)
274         {
275             proxyObject=null;
276             return;
277         }
278         
279         log.debug("setManagedResource");
280         if (!"objectreference".equalsIgnoreCase(type))
281             throw new InvalidTargetObjectTypeException JavaDoc(type);
282
283         if (_object==null)
284         {
285             // first set so define attributes etc.
286
_object=proxyObject;
287             
288             defineManagedResource();
289         }
290         else
291             _object=proxyObject;
292     }
293
294     /* ------------------------------------------------------------ */
295     /** Define the Managed Resource.
296      * This method is called the first time setManagedResource is
297      * called with a non-null object. It should be implemented by a
298      * derived ModelMBean to define the attributes and operations
299      * after an initial object has been set.
300      */

301     protected void defineManagedResource()
302     {}
303     
304     /* ------------------------------------------------------------ */
305     /** Not Supported.
306      * Use RequiredModelMBean for this style of MBean creation.
307      */

308     public void setModelMBeanInfo(ModelMBeanInfo JavaDoc info)
309         throws MBeanException JavaDoc,
310                RuntimeOperationsException JavaDoc
311     {
312         throw new Error JavaDoc("setModelMBeanInfo not supported");
313     }
314     
315     /* ------------------------------------------------------------ */
316     /** Define an attribute on the managed object.
317      * The meta data is defined by looking for standard getter and
318      * setter methods. Descriptions are obtained with a call to
319      * findDescription with the attribute name.
320      * @param name The name of the attribute. Normal java bean
321      * capitlization is enforced on this name.
322      */

323     public synchronized void defineAttribute(String JavaDoc name)
324     {
325         defineAttribute(name,true,false);
326     }
327     
328     /* ------------------------------------------------------------ */
329     /** Define an attribute on the managed object.
330      * The meta data is defined by looking for standard getter and
331      * setter methods. Descriptions are obtained with a call to
332      * findDescription with the attribute name.
333      * @param name The name of the attribute. Normal java bean
334      * capitlization is enforced on this name.
335      * @param writable If false, do not look for a setter.
336      */

337     public synchronized void defineAttribute(String JavaDoc name, boolean writable)
338     {
339         defineAttribute(name,writable,false);
340     }
341     
342     /* ------------------------------------------------------------ */
343     /** Define an attribute on the managed object.
344      * The meta data is defined by looking for standard getter and
345      * setter methods. Descriptions are obtained with a call to
346      * findDescription with the attribute name.
347      * @param name The name of the attribute. Normal java bean
348      * capitlization is enforced on this name.
349      * @param writable If false, do not look for a setter.
350      * @param onMBean .
351      */

352     public synchronized void defineAttribute(String JavaDoc name,
353                                              boolean writable,
354                                              boolean onMBean)
355     {
356         _dirty=true;
357         
358         String JavaDoc uName=name.substring(0,1).toUpperCase()+name.substring(1);
359         name=java.beans.Introspector.decapitalize(name);
360         Class JavaDoc oClass=onMBean?this.getClass():_object.getClass();
361
362         Class JavaDoc type=null;
363         Method JavaDoc getter=null;
364         Method JavaDoc setter=null;
365         Method JavaDoc[] methods=oClass.getMethods();
366         for (int m=0;m<methods.length;m++)
367         {
368             if ((methods[m].getModifiers()&Modifier.PUBLIC)==0)
369                 continue;
370
371             // Look for a getter
372
if (methods[m].getName().equals("get"+uName) &&
373                 methods[m].getParameterTypes().length==0)
374             {
375                 if (getter!=null)
376                     throw new IllegalArgumentException JavaDoc("Multiple getters for attr "+name);
377                 getter=methods[m];
378                 if (type!=null &&
379                     !type.equals(methods[m].getReturnType()))
380                     throw new IllegalArgumentException JavaDoc("Type conflict for attr "+name);
381                 type=methods[m].getReturnType();
382             }
383
384             // Look for an is getter
385
if (methods[m].getName().equals("is"+uName) &&
386                 methods[m].getParameterTypes().length==0)
387             {
388                 if (getter!=null)
389                     throw new IllegalArgumentException JavaDoc("Multiple getters for attr "+name);
390                 getter=methods[m];
391                 if (type!=null &&
392                     !type.equals(methods[m].getReturnType()))
393                     throw new IllegalArgumentException JavaDoc("Type conflict for attr "+name);
394                 type=methods[m].getReturnType();
395             }
396
397             // look for a setter
398
if (writable &&
399                 methods[m].getName().equals("set"+uName) &&
400                 methods[m].getParameterTypes().length==1)
401             {
402                 if (setter!=null)
403                     throw new IllegalArgumentException JavaDoc("Multiple setters for attr "+name);
404                 setter=methods[m];
405                 if (type!=null &&
406                     !type.equals(methods[m].getParameterTypes()[0]))
407                     throw new IllegalArgumentException JavaDoc("Type conflict for attr "+name);
408                 type=methods[m].getParameterTypes()[0];
409             }
410         }
411
412         if (getter==null && setter==null)
413             throw new IllegalArgumentException JavaDoc("No getter or setters found for "+name);
414         
415         try
416         {
417             // Remember the methods
418
_getter.put(name,getter);
419             _setter.put(name,setter);
420             // create and add the info
421
_attributes.add(new ModelMBeanAttributeInfo JavaDoc(name,
422                                                         findDescription(name),
423                                                         getter,
424                                                         setter));
425         }
426         catch(Exception JavaDoc e)
427         {
428             log.warn(LogSupport.EXCEPTION,e);
429             throw new IllegalArgumentException JavaDoc(e.toString());
430         }
431     }
432
433     /* ------------------------------------------------------------ */
434     /** Define an attribute.
435      * Explicit definition of an attribute. Reflection is used to
436      * locate the actual getter and setter methods.
437      * @param attrInfo ModelMBeanAttributeInfo.
438      */

439     public synchronized void defineAttribute(ModelMBeanAttributeInfo JavaDoc attrInfo)
440     {
441         if (_object==null)
442             throw new IllegalStateException JavaDoc("No Object");
443         
444         _dirty=true;
445         
446         String JavaDoc name=attrInfo.getName();
447         String JavaDoc uName=name.substring(0,1).toUpperCase()+name.substring(1);
448         Class JavaDoc oClass=_object.getClass();
449
450         try
451         {
452             Class JavaDoc type=TypeUtil.fromName(attrInfo.getType());
453             if (type==null)
454                 type=Thread.currentThread().getContextClassLoader().loadClass(attrInfo.getType());
455         
456             Method JavaDoc getter=null;
457             Method JavaDoc setter=null;
458             
459             if (attrInfo.isReadable())
460                 getter=oClass.getMethod((attrInfo.isIs()?"is":"get")+uName,(java.lang.Class JavaDoc[])null);
461             
462             if (attrInfo.isWritable())
463                 setter=oClass.getMethod("set"+uName,new Class JavaDoc[] {type});
464             
465             _getter.put(name,getter);
466             _setter.put(name,setter);
467             _attributes.add(attrInfo);
468         }
469         catch(Exception JavaDoc e)
470         {
471             log.warn(LogSupport.EXCEPTION,e);
472             throw new IllegalArgumentException JavaDoc(e.toString());
473         }
474     }
475     
476     /* ------------------------------------------------------------ */
477     /** Define an operation on the managed object.
478      * Defines an operation with no parameters. Refection is used to
479      * determine the return type and the description is found with a
480      * call to findDescription on "name()".
481      * @param name Name of the method call
482      * @param impact Impact as defined in MBeanOperationInfo
483      */

484     public synchronized void defineOperation(String JavaDoc name,int impact)
485     {
486         defineOperation(name,null,impact,false);
487     }
488     
489     /* ------------------------------------------------------------ */
490     /** Define an operation on the managed object.
491      * Defines an operation with parameters. Refection is used to
492      * determine find the method and it's return type. The description
493      * of the method is found with a call to findDescription on
494      * "name(signature)". The name and description of each parameter
495      * is found with a call to findDescription with
496      * "name(partialSignature", the returned description is for the
497      * last parameter of the partial signature and is assumed to start
498      * with the parameter name, followed by a colon.
499      * @param name The name of the method call.
500      * @param signature The types of the operation parameters.
501      * @param impact Impact as defined in MBeanOperationInfo
502      */

503     public synchronized void defineOperation(String JavaDoc name,
504                                              String JavaDoc[] signature,
505                                              int impact)
506     {
507         defineOperation(name,signature,impact,false);
508     }
509         
510     /* ------------------------------------------------------------ */
511     /** Define an operation on the managed object.
512      * Defines an operation with parameters. Refection is used to
513      * determine find the method and it's return type. The description
514      * of the method is found with a call to findDescription on
515      * "name(signature)". The name and description of each parameter
516      * is found with a call to findDescription with
517      * "name(partialSignature", the returned description is for the
518      * last parameter of the partial signature and is assumed to start
519      * with the parameter name, followed by a colon.
520      * @param name The name of the method call.
521      * @param signature The types of the operation parameters.
522      * @param impact Impact as defined in MBeanOperationInfo
523      * @param onMBean true if the operation is defined on the mbean
524      */

525     public synchronized void defineOperation(String JavaDoc name,
526             String JavaDoc[] signature,
527             int impact,
528             boolean onMBean)
529     {
530         _dirty=true;
531         Class JavaDoc oClass=onMBean?this.getClass():_object.getClass();
532         if (signature==null) signature=new String JavaDoc[0];
533
534         try
535         {
536             Class JavaDoc[] types = new Class JavaDoc[signature.length];
537             MBeanParameterInfo JavaDoc[] pInfo = new
538                 MBeanParameterInfo JavaDoc[signature.length];
539
540             // Check types and build methodKey
541
String JavaDoc methodKey=name+"(";
542             for (int i=0;i<signature.length;i++)
543             {
544                 Class JavaDoc type=TypeUtil.fromName(signature[i]);
545                 if (type==null)
546                     type=Thread.currentThread().getContextClassLoader().loadClass(signature[i]);
547                 types[i]=type;
548                 signature[i]=type.isPrimitive()?TypeUtil.toName(type):signature[i];
549                 methodKey+=(i>0?",":"")+signature[i];
550             }
551             methodKey+=")";
552
553             // Build param infos
554
for (int i=0;i<signature.length;i++)
555             {
556                 String JavaDoc description=findDescription(methodKey+"["+i+"]");
557                 int colon=description.indexOf(":");
558                 if (colon<0)
559                 {
560                     description="param"+i+":"+description;
561                     colon=description.indexOf(":");
562                 }
563                 pInfo[i]=new
564                     MBeanParameterInfo JavaDoc(description.substring(0,colon).trim(),
565                                        signature[i],
566                                        description.substring(colon+1).trim());
567             }
568
569             // build the operation info
570
Method JavaDoc method=oClass.getMethod(name,types);
571             Class JavaDoc returnClass=method.getReturnType();
572             _method.put(methodKey,method);
573             _operations.add(new ModelMBeanOperationInfo JavaDoc
574                 (name,
575                  findDescription(methodKey),
576                  pInfo,
577                  returnClass.isPrimitive()?TypeUtil.toName(returnClass):(returnClass.getName()),
578                  impact));
579         }
580         catch(Exception JavaDoc e)
581         {
582             log.warn("operation "+name,e);
583             throw new IllegalArgumentException JavaDoc(e.toString());
584         }
585         
586     }
587     
588     /* ------------------------------------------------------------ */
589     /** Define an operation.
590      * Explicit definition of an operation. Reflection is used to
591      * locate method called.
592      * @param opInfo
593      */

594     public synchronized void defineOperation(ModelMBeanOperationInfo JavaDoc opInfo)
595     {
596         _dirty=true;
597         Class JavaDoc oClass=_object.getClass();
598         
599         try
600         {
601             MBeanParameterInfo JavaDoc[] pInfo = opInfo.getSignature();
602             
603             Class JavaDoc[] types = new Class JavaDoc[pInfo.length];
604             String JavaDoc method=opInfo.getName()+"(";
605             for (int i=0;i<pInfo.length;i++)
606             {
607                 Class JavaDoc type=TypeUtil.fromName(pInfo[i].getType());
608                 if (type==null)
609                     type=Thread.currentThread().getContextClassLoader().loadClass(pInfo[i].getType());
610                 types[i]=type;
611                 method+=(i>0?",":"")+pInfo[i].getType();
612             }
613             method+=")";
614
615             _method.put(method,oClass.getMethod(opInfo.getName(),types));
616             _operations.add(opInfo);
617         }
618         catch(Exception JavaDoc e)
619         {
620             log.warn(LogSupport.EXCEPTION,e);
621             throw new IllegalArgumentException JavaDoc(e.toString());
622         }
623     }
624     
625     /* ------------------------------------------------------------ */
626     public synchronized MBeanInfo JavaDoc getMBeanInfo()
627     {
628         log.debug("getMBeanInfo");
629
630         if (_dirty)
631         {
632             _dirty=false;
633             ModelMBeanAttributeInfo JavaDoc[] attributes = (ModelMBeanAttributeInfo JavaDoc[])
634                 _attributes.toArray(new ModelMBeanAttributeInfo JavaDoc[_attributes.size()]);
635             ModelMBeanOperationInfo JavaDoc[] operations = (ModelMBeanOperationInfo JavaDoc[])
636                 _operations.toArray(new ModelMBeanOperationInfo JavaDoc[_operations.size()]);
637             ModelMBeanNotificationInfo JavaDoc[] notifications =(ModelMBeanNotificationInfo JavaDoc[])
638                 _notifications.toArray(new ModelMBeanNotificationInfo JavaDoc[_notifications.size()]);
639
640             _beanInfo =
641                 new ModelMBeanInfoSupport JavaDoc(_object.getClass().getName(),
642                                           findDescription(null),
643                                           attributes,
644                                           null,
645                                           operations,
646                                           notifications);
647         }
648             
649         return _beanInfo;
650     }
651   
652     /* ------------------------------------------------------------ */
653     public Object JavaDoc getAttribute(String JavaDoc name)
654         throws AttributeNotFoundException JavaDoc,
655                MBeanException JavaDoc,
656                ReflectionException JavaDoc
657     {
658         if(log.isDebugEnabled())log.debug("getAttribute "+name);
659         Method JavaDoc getter = (Method JavaDoc)_getter.get(name);
660         if (getter==null)
661             throw new AttributeNotFoundException JavaDoc(name);
662         try
663         {
664             Object JavaDoc o=_object;
665             if (getter.getDeclaringClass().isInstance(this))
666                 o=this;
667             return getter.invoke(o,(java.lang.Object JavaDoc[])null);
668         }
669         catch(IllegalAccessException JavaDoc e)
670         {
671             log.warn(LogSupport.EXCEPTION,e);
672             throw new AttributeNotFoundException JavaDoc(e.toString());
673         }
674         catch(InvocationTargetException JavaDoc e)
675         {
676             log.warn(LogSupport.EXCEPTION,e);
677             throw new ReflectionException JavaDoc((Exception JavaDoc)e.getTargetException());
678         }
679     }
680     
681     /* ------------------------------------------------------------ */
682     public AttributeList JavaDoc getAttributes(String JavaDoc[] names)
683     {
684         log.debug("getAttributes");
685         AttributeList JavaDoc results=new AttributeList JavaDoc(names.length);
686         for (int i=0;i<names.length;i++)
687         {
688             try
689             {
690                 results.add(new Attribute JavaDoc(names[i],
691                                           getAttribute(names[i])));
692             }
693             catch(Exception JavaDoc e)
694             {
695                 log.warn(LogSupport.EXCEPTION,e);
696             }
697         }
698         return results;
699     }
700     
701     
702     /* ------------------------------------------------------------ */
703     public void setAttribute(Attribute JavaDoc attr)
704         throws AttributeNotFoundException JavaDoc,
705                InvalidAttributeValueException JavaDoc,
706                MBeanException JavaDoc,
707                ReflectionException JavaDoc
708     {
709         if (attr==null)
710             return;
711
712         if(log.isDebugEnabled())log.debug("setAttribute "+attr.getName()+"="+attr.getValue());
713         Method JavaDoc setter = (Method JavaDoc)_setter.get(attr.getName());
714         if (setter==null)
715             throw new AttributeNotFoundException JavaDoc(attr.getName());
716         try
717         {
718             Object JavaDoc o=_object;
719             if (setter.getDeclaringClass().isInstance(this))
720                 o=this;
721             setter.invoke(o,new Object JavaDoc[]{attr.getValue()});
722         }
723         catch(IllegalAccessException JavaDoc e)
724         {
725             log.warn(LogSupport.EXCEPTION,e);
726             throw new AttributeNotFoundException JavaDoc(e.toString());
727         }
728         catch(InvocationTargetException JavaDoc e)
729         {
730             log.warn(LogSupport.EXCEPTION,e);
731             throw new ReflectionException JavaDoc((Exception JavaDoc)e.getTargetException());
732         }
733     }
734     
735     /* ------------------------------------------------------------ */
736     public AttributeList JavaDoc setAttributes(AttributeList JavaDoc attrs)
737     {
738         log.debug("setAttributes");
739
740         AttributeList JavaDoc results=new AttributeList JavaDoc(attrs.size());
741         Iterator JavaDoc iter = attrs.iterator();
742         while(iter.hasNext())
743         {
744             try
745             {
746                 Attribute JavaDoc attr=(Attribute JavaDoc)iter.next();
747                 setAttribute(attr);
748                 results.add(new Attribute JavaDoc(attr.getName(),
749                                           getAttribute(attr.getName())));
750             }
751             catch(Exception JavaDoc e)
752             {
753                 log.warn(LogSupport.EXCEPTION,e);
754             }
755         }
756         return results;
757     }
758
759     /* ------------------------------------------------------------ */
760     public Object JavaDoc invoke(String JavaDoc name, Object JavaDoc[] params, String JavaDoc[] signature)
761         throws MBeanException JavaDoc,
762                ReflectionException JavaDoc
763     {
764         if(log.isDebugEnabled())log.debug("invoke "+name);
765
766         String JavaDoc methodKey=name+"(";
767         if (signature!=null)
768             for (int i=0;i<signature.length;i++)
769                 methodKey+=(i>0?",":"")+signature[i];
770         methodKey+=")";
771
772         try
773         {
774             Method JavaDoc method = (Method JavaDoc)_method.get(methodKey);
775             if (method==null)
776                 throw new NoSuchMethodException JavaDoc(methodKey);
777
778             Object JavaDoc o=_object;
779             if (method.getDeclaringClass().isInstance(this))
780                 o=this;
781             return method.invoke(o,params);
782         }
783         catch(NoSuchMethodException JavaDoc e)
784         {
785             log.warn(LogSupport.EXCEPTION,e);
786             throw new ReflectionException JavaDoc(e);
787         }
788         catch(IllegalAccessException JavaDoc e)
789         {
790             log.warn(LogSupport.EXCEPTION,e);
791             throw new MBeanException JavaDoc(e);
792         }
793         catch(InvocationTargetException JavaDoc e)
794         {
795             log.warn(LogSupport.EXCEPTION,e);
796             throw new ReflectionException JavaDoc((Exception JavaDoc)e.getTargetException());
797         }
798         
799     }
800     
801     /* ------------------------------------------------------------ */
802     public void load()
803         throws MBeanException JavaDoc,
804                RuntimeOperationsException JavaDoc,
805                InstanceNotFoundException JavaDoc
806     {
807         log.debug("load");
808     }
809     
810     /* ------------------------------------------------------------ */
811     public void store()
812         throws MBeanException JavaDoc,
813                RuntimeOperationsException JavaDoc,
814                InstanceNotFoundException JavaDoc
815     {
816         log.debug("store");
817     }
818
819     /* ------------------------------------------------------------ */
820     public void addNotificationListener(NotificationListener JavaDoc listener,
821                                         NotificationFilter JavaDoc filter,
822                                         Object JavaDoc handback)
823         throws IllegalArgumentException JavaDoc
824     {
825         log.debug("addNotificationListener");
826     }
827     
828     /* ------------------------------------------------------------ */
829     public MBeanNotificationInfo JavaDoc[] getNotificationInfo()
830     {
831         log.debug("getNotificationInfo");
832         return null;
833     }
834     
835     /* ------------------------------------------------------------ */
836     public void removeNotificationListener(NotificationListener JavaDoc listener)
837         throws ListenerNotFoundException JavaDoc
838     {
839         log.debug("removeNotificationListener");
840     }
841
842     /* ------------------------------------------------------------ */
843     public void addAttributeChangeNotificationListener(NotificationListener JavaDoc listener,
844                                                String JavaDoc name,
845                                                Object JavaDoc handback)
846         throws MBeanException JavaDoc,
847                RuntimeOperationsException JavaDoc,
848                IllegalArgumentException JavaDoc
849     {
850         log.debug("addAttributeChangeNotificationListener");
851     }
852     
853     /* ------------------------------------------------------------ */
854     public void removeAttributeChangeNotificationListener(NotificationListener JavaDoc listener,
855                                                           String JavaDoc name)
856         throws MBeanException JavaDoc,
857                RuntimeOperationsException JavaDoc,
858                ListenerNotFoundException JavaDoc
859     {
860         log.debug("removeAttributeChangeNotificationListener");
861     }
862     
863     /* ------------------------------------------------------------ */
864     public void sendAttributeChangeNotification(Attribute JavaDoc oldAttr,
865                                                 Attribute JavaDoc newAttr)
866         throws MBeanException JavaDoc,
867                RuntimeOperationsException JavaDoc
868     {
869         log.debug("sendAttributeChangeNotification");
870     }
871     
872     /* ------------------------------------------------------------ */
873     public void sendAttributeChangeNotification(AttributeChangeNotification JavaDoc notify)
874         throws MBeanException JavaDoc,
875                RuntimeOperationsException JavaDoc
876     {
877         log.debug("sendAttributeChangeNotification");
878     }
879     
880     /* ------------------------------------------------------------ */
881     public void sendNotification(String JavaDoc notify)
882         throws MBeanException JavaDoc,
883                RuntimeOperationsException JavaDoc
884     {
885         log.debug("sendNotification");
886     }
887     
888     /* ------------------------------------------------------------ */
889     public void sendNotification(Notification JavaDoc notify)
890         throws MBeanException JavaDoc,
891                RuntimeOperationsException JavaDoc
892     {
893         log.debug("sendNotification");
894     }
895
896     /* ------------------------------------------------------------ */
897     /* Find MBean descriptions.
898      * MBean descriptions are searched for in ResourceBundles. Bundles
899      * are looked for in a mbean.property files within each package of
900      * the MBean class inheritance hierachy.
901      * Once a bundle is found, the key is added to object names in the
902      * following order: fully qualied managed resource class name, tail
903      * managed resource class name, tail mbean class name. The string
904      * "MBean" is stripped from the tail of any name.
905      * <P>For example, if the class a.b.C is managed by a MBean
906      * p.q.RMBean which is derived from p.SMBean, then the seach order
907      * for a key x is as follows:<PRE>
908      * bundle: p.q.mbean name: a.b.C.x
909      * bundle: p.q.mbean name: C.x
910      * bundle: p.q.mbean name: R.x
911      * bundle: p.mbean name: a.b.C.x
912      * bundle: p.mbean name: C.x
913      * bundle: p.mbean name: S.x
914      * </PRE>
915      * <P>The convention used for keys passed to this method are:<PRE>
916      * null or empty - Object description
917      * xxx - Attribute xxx description
918      * xxx() - Simple operation xxx description
919      * xxx(type,..) - Operation xxx with signature desciption
920      * xxx(type,..)[n] - Param n of operation xxx description
921      * </PRE>
922      * @param key
923      * @return Description string.
924      */

925     private String JavaDoc findDescription(String JavaDoc key)
926     {
927         Class JavaDoc lookIn = this.getClass();
928
929         // Array of possible objectNames
930
String JavaDoc[] objectNames=new String JavaDoc[3];
931         objectNames[0]=_object.getClass().getName();
932         if (objectNames[0].indexOf(".")>=0)
933             objectNames[1]=objectNames[0].substring(objectNames[0].lastIndexOf(".")+1);
934
935         while(lookIn!=null)
936         {
937             String JavaDoc pkg=lookIn.getName();
938             int lastDot= pkg.lastIndexOf(".");
939             if (lastDot>0)
940             {
941                 objectNames[2]=pkg.substring(lastDot+1);
942                 pkg=pkg.substring(0,lastDot);
943             }
944             else
945             {
946                 objectNames[2]=pkg;
947                 pkg=null;
948             }
949
950             String JavaDoc resource=(pkg==null?"mbean":(pkg.replace('.','/')+"/mbean"));
951             if(log.isTraceEnabled())log.trace("Look for: "+resource);
952
953             try
954             {
955                 ResourceBundle JavaDoc bundle=
956                     ResourceBundle.getBundle(resource,
957                                              Locale.getDefault(),
958                                              _object.getClass().getClassLoader());
959             
960                 if(log.isTraceEnabled())log.trace("Bundle "+resource);
961                 
962                 for (int i=0;i<objectNames.length;i++)
963                 {
964                     String JavaDoc name=objectNames[i];
965                     
966                     if (name==null)
967                         continue;
968                     if (name.endsWith("MBean"))
969                         name=name.substring(0,name.length()-5);
970                     if (key!=null && key.length()>0)
971                         name+="."+key;
972
973                     try{
974                         String JavaDoc description=bundle.getString(name);
975                         if (description!=null && description.length()>0)
976                             return description;
977                     }
978                     catch(Exception JavaDoc e) { if(log.isTraceEnabled())log.trace(e.toString()); }
979                 }
980             }
981             catch(Exception JavaDoc e) { if(log.isTraceEnabled())log.trace(e.toString()); }
982
983             lookIn=lookIn.getSuperclass();
984         }
985
986         if (key==null || key.length()==0)
987             return objectNames[0];
988         
989         return key;
990     }
991     
992     /* ------------------------------------------------------------ */
993     /** Create a new ObjectName.
994      * Return a new object name. The default implementation is the
995      * results of uniqueObjectName(baseObjectName), if baseObjectName
996      * is not set, then the results of uniqueObjectName(defaultDomain+":");
997      * @return The Object name
998      */

999     protected ObjectName JavaDoc newObjectName(MBeanServer JavaDoc server)
1000    {
1001        // Create own ObjectName of the form:
1002
// package:class=id
1003
if (_baseObjectName!=null)
1004        {
1005            if (_baseObjectName.indexOf(':')>=0)
1006                return uniqueObjectName(server,_baseObjectName);
1007            return uniqueObjectName(server,getDefaultDomain()+":"+
1008                                    _baseObjectName);
1009        }
1010        return uniqueObjectName(server,getDefaultDomain()+":");
1011    }
1012
1013    /* ------------------------------------------------------------ */
1014    public void setBaseObjectName(String JavaDoc s)
1015    {
1016        _baseObjectName=s;
1017    }
1018    
1019    /* ------------------------------------------------------------ */
1020    public String JavaDoc getBaseObjectName()
1021    {
1022        return _baseObjectName;
1023    }
1024    
1025    /* ------------------------------------------------------------ */
1026    /** Pre registration notification.
1027     * If this method is specialized by a derived class that may set
1028     * the objectName, then it should call this implementation with
1029     * the new objectName.
1030     * @param server
1031     * @param oName
1032     * @return The ObjectName to use.
1033     */

1034    public synchronized ObjectName JavaDoc preRegister(MBeanServer JavaDoc server, ObjectName JavaDoc oName)
1035    {
1036        _mBeanServer=server;
1037        _objectName=oName;
1038        if (_objectName==null)
1039        {
1040            try{oName=newObjectName(server);}
1041            catch(Exception JavaDoc e){log.warn(LogSupport.EXCEPTION,e);}
1042        }
1043        if(log.isDebugEnabled())log.debug("preRegister "+_objectName+" -> "+oName);
1044        _objectName=oName;
1045
1046        return _objectName;
1047    }
1048    
1049
1050    /* ------------------------------------------------------------ */
1051    public void postRegister(Boolean JavaDoc ok)
1052    {
1053        if (ok.booleanValue())
1054            log.info("Registered "+_objectName);
1055        else
1056        {
1057            _mBeanServer=null;
1058            _objectName=null;
1059        }
1060    }
1061
1062    /* ------------------------------------------------------------ */
1063    public void preDeregister()
1064    {
1065        log.info("Deregister "+_objectName);
1066        getComponentMBeans(null,_components);
1067        _components.clear();
1068    }
1069    
1070    /* ------------------------------------------------------------ */
1071    /** Post Deregister.
1072     * This implementation destroys this MBean and it cannot be used again.
1073     */

1074    public void postDeregister()
1075    {
1076        _beanInfo=null;
1077        _mBeanServer=null;
1078        _object=null;
1079        _objectName=null;
1080        if (_getter!=null)
1081            _getter.clear();
1082        _getter=null;
1083        if (_setter!=null)
1084            _setter.clear();
1085        _setter=null;
1086        if (_method!=null)
1087            _method.clear();
1088        _method=null;
1089        if (_attributes!=null)
1090            _attributes.clear();
1091        _attributes=null;
1092        if (_operations!=null)
1093            _operations.clear();
1094        _operations=null;
1095        if (_notifications!=null)
1096            _notifications.clear();
1097        _notifications=null;
1098    }
1099
1100    /* ------------------------------------------------------------ */
1101    /** Add an id clause to a JMX object name.
1102     * Used to make unique objectnames when there are no other
1103     * distinguishing attributes.
1104     * If the passed object name ends with '=', just a unique ID is
1105     * added. Otherwise and classname= clause is added.
1106     * @param objectName
1107     * @return objectName with id= class.
1108     */

1109    public synchronized ObjectName JavaDoc uniqueObjectName(MBeanServer JavaDoc server,
1110                                                    String JavaDoc objectName)
1111    {
1112        return uniqueObjectName(server,_object,objectName);
1113    }
1114    
1115    /* ------------------------------------------------------------ */
1116    public synchronized ObjectName JavaDoc uniqueObjectName(MBeanServer JavaDoc server,
1117                                                    Object JavaDoc object,
1118                                                    String JavaDoc objectName)
1119    {
1120        if (!objectName.endsWith("="))
1121        {
1122            String JavaDoc className = object.getClass().getName();
1123            if (className.indexOf(".")>0)
1124                className=className.substring(className.lastIndexOf(".")+1);
1125            if (className.endsWith("MBean"))
1126                className=className.substring(0,className.length()-5);
1127            if (!objectName.endsWith(":"))
1128                objectName+=",";
1129            objectName+=className+"=";
1130        }
1131
1132        ObjectName JavaDoc oName=null;
1133        try
1134        {
1135            while(true)
1136            {
1137                Integer JavaDoc id=(Integer JavaDoc)__objectId.get(objectName);
1138                if (id==null)
1139                    id=new Integer JavaDoc(0);
1140                oName=new ObjectName JavaDoc(objectName+id);
1141                id=new Integer JavaDoc(id.intValue()+1);
1142                __objectId.put(objectName,id);
1143                
1144                // If no server, this must be unique
1145
if (server==null)
1146                    break;
1147                
1148                // Otherwise let's check it is unique
1149
// if not found then it is unique
1150
if (!server.isRegistered(oName))
1151                    break;
1152            }
1153        }
1154        catch(Exception JavaDoc e)
1155        {
1156            log.warn(LogSupport.EXCEPTION,e);
1157        }
1158
1159        return oName;
1160    }
1161
1162
1163    /* ------------------------------------------------------------ */
1164    /** Get Component MBeans.
1165     * Creates, registers and deregisters MBeans for an array of components.
1166     * On each call the passed map is used to determine components that have
1167     * already been registers and those that need to be deregistered.
1168     * @param components the components.
1169     * @param map A map of previously registered components to object
1170     * name. If null is passed, a default map for the mbean is used.
1171     * @return An array of ObjectNames for each component.
1172     */

1173    protected ObjectName JavaDoc[] getComponentMBeans(Object JavaDoc[] components, Map JavaDoc map)
1174    {
1175        if (map==null)
1176            map=_components;
1177        ObjectName JavaDoc[] beans=null;
1178        if (components==null)
1179            beans = new ObjectName JavaDoc[0];
1180        else
1181        {
1182            beans = new ObjectName JavaDoc[components==null?0:components.length];
1183
1184            // Add new beans
1185
for (int i=0;i<components.length;i++)
1186            {
1187                ObjectName JavaDoc on = (ObjectName JavaDoc)map.get(components[i]);
1188                if (on==null)
1189                {
1190                    ModelMBean JavaDoc mbean = mbeanFor(components[i]);
1191                    if (mbean==null)
1192                        log.warn("No mbean for "+components[i]);
1193                    else
1194                    {
1195                        try
1196                        {
1197                            if (mbean instanceof ModelMBeanImpl)
1198                            {
1199                                ((ModelMBeanImpl)mbean).setBaseObjectName(getObjectName().toString());
1200                                on=getMBeanServer().registerMBean(mbean,null).getObjectName();
1201                            }
1202                            else
1203                            {
1204                                on=uniqueObjectName(getMBeanServer(),
1205                                                    components[i],
1206                                                    getObjectName().toString());
1207                                on=getMBeanServer().registerMBean(mbean,on).getObjectName();
1208                            }
1209                            map.put(components[i],on);
1210                        }
1211                        catch (Exception JavaDoc e)
1212                        {
1213                            log.warn(LogSupport.EXCEPTION,e);
1214                        }
1215                    }
1216                }
1217                beans[i]=on;
1218            }
1219        }
1220        
1221        // Delete old beans
1222
if (components==null || map.size()>components.length)
1223        {
1224            Object JavaDoc[] to_delete=new Object JavaDoc[map.size()-beans.length];
1225            int d=0;
1226            Iterator JavaDoc iter = map.keySet().iterator();
1227            keys:
1228            while(iter.hasNext())
1229            {
1230                Object JavaDoc bean = iter.next();
1231                if (components!=null)
1232                {
1233                    for(int i=0;i<components.length;i++)
1234                        if (components[i]==bean)
1235                            continue keys;
1236                }
1237                to_delete[d++]=bean;
1238            }
1239
1240            for (;d-->0;)
1241            {
1242                try{getMBeanServer().unregisterMBean((ObjectName JavaDoc)map.remove(to_delete[d]));}
1243                catch (Exception JavaDoc e) {log.warn(LogSupport.EXCEPTION,e);}
1244            }
1245        }
1246        
1247        return beans;
1248    }
1249    
1250    /** Unregister mbeans for already registered components
1251     * @param map
1252     */

1253    protected void destroyComponentMBeans (Map JavaDoc map)
1254    {
1255        //if no map of registered mbean names is passed,
1256
//use the default map
1257
if (null==map)
1258            map = _components;
1259        
1260        if (map==null)
1261            return;
1262        
1263        Iterator JavaDoc itor = map.values().iterator();
1264        while (itor.hasNext())
1265        {
1266            try
1267            {
1268                ObjectName JavaDoc o = (ObjectName JavaDoc)itor.next();
1269                getMBeanServer().unregisterMBean(o);
1270                itor.remove();
1271            }
1272            catch (Exception JavaDoc e) {log.warn(LogSupport.EXCEPTION,e);}
1273        }
1274            
1275    }
1276}
1277
Popular Tags