KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb3 > service > ServiceMBeanDelegate


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.ejb3.service;
23
24 import java.lang.reflect.Method JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import javax.management.Attribute JavaDoc;
29 import javax.management.AttributeList JavaDoc;
30 import javax.management.AttributeNotFoundException JavaDoc;
31 import javax.management.DynamicMBean JavaDoc;
32 import javax.management.InstanceNotFoundException JavaDoc;
33 import javax.management.InvalidAttributeValueException JavaDoc;
34 import javax.management.MBeanAttributeInfo JavaDoc;
35 import javax.management.MBeanException JavaDoc;
36 import javax.management.MBeanInfo JavaDoc;
37 import javax.management.MBeanOperationInfo JavaDoc;
38 import javax.management.MBeanParameterInfo JavaDoc;
39 import javax.management.MBeanServer JavaDoc;
40 import javax.management.ObjectName JavaDoc;
41 import javax.management.ReflectionException JavaDoc;
42 import javax.management.StandardMBean JavaDoc;
43 import javax.management.NotCompliantMBeanException JavaDoc;
44
45 import org.jboss.logging.Logger;
46 import org.jboss.util.Classes;
47
48 /**
49  * @author <a HREF="mailto:kabir.khan@jboss.org">Kabir Khan</a>
50  * @version $Revision: 57005 $
51  */

52 public class ServiceMBeanDelegate implements DynamicMBean JavaDoc
53 {
54    private static final Logger log = Logger.getLogger(ServiceMBeanDelegate.class);
55    
56    MBeanServer JavaDoc server;
57    ServiceContainer container;
58    ObjectName JavaDoc serviceOn;
59    MBeanInfo JavaDoc mbeanInfo;
60
61    HashMap JavaDoc<String JavaDoc, Method JavaDoc> getterMethods = new HashMap JavaDoc<String JavaDoc, Method JavaDoc>();
62    HashSet JavaDoc<String JavaDoc> getterBlackList = new HashSet JavaDoc<String JavaDoc>();
63    HashMap JavaDoc<String JavaDoc, Method JavaDoc> setterMethods = new HashMap JavaDoc<String JavaDoc, Method JavaDoc>();
64    HashSet JavaDoc<String JavaDoc> setterBlackList = new HashSet JavaDoc<String JavaDoc>();
65    HashMap JavaDoc<String JavaDoc, Method JavaDoc> operations = new HashMap JavaDoc<String JavaDoc, Method JavaDoc>();
66    HashSet JavaDoc<String JavaDoc> operationBlackList = new HashSet JavaDoc<String JavaDoc>();
67
68    public ServiceMBeanDelegate(MBeanServer JavaDoc server, ServiceContainer container, Class JavaDoc intf, ObjectName JavaDoc on)
69    {
70       this.container = container;
71       this.server = server;
72       serviceOn = on;
73       StandardMBean JavaDoc mbean = null;
74       try
75       {
76          mbean = new StandardMBean JavaDoc(container.getSingleton(), intf);
77       }
78       catch (NotCompliantMBeanException JavaDoc e)
79       {
80          throw new RuntimeException JavaDoc(e);
81       }
82       mbeanInfo = mbean.getMBeanInfo();
83    }
84
85    public ObjectName JavaDoc getObjectName()
86    {
87       return serviceOn;
88    }
89
90    public void register(ObjectName JavaDoc on, Class JavaDoc intf) throws Exception JavaDoc
91    {
92       server.registerMBean(this, serviceOn);
93    }
94
95    public void unregister() throws Exception JavaDoc
96    {
97       server.unregisterMBean(serviceOn);
98    }
99
100    public Object JavaDoc getAttribute(String JavaDoc attribute) throws AttributeNotFoundException JavaDoc,
101                                                        MBeanException JavaDoc, ReflectionException JavaDoc
102    {
103       Method JavaDoc getter = getGetter(attribute);
104
105       try
106       {
107          return container.localInvoke(getter, new Object JavaDoc[0]);
108       }
109       catch (Throwable JavaDoc t)
110       {
111          if (t instanceof Exception JavaDoc) throw new MBeanException JavaDoc((Exception JavaDoc) t);
112          else throw new RuntimeException JavaDoc(t);
113       }
114    }
115
116    public void setAttribute(Attribute JavaDoc attribute) throws AttributeNotFoundException JavaDoc,
117                                                         InvalidAttributeValueException JavaDoc, MBeanException JavaDoc, ReflectionException JavaDoc
118    {
119       Method JavaDoc setter = getSetter(attribute);
120       try
121       {
122          container.localInvoke(setter, new Object JavaDoc[]{attribute.getValue()});
123       }
124       catch (Throwable JavaDoc t)
125       {
126          if (t instanceof Exception JavaDoc) throw new MBeanException JavaDoc((Exception JavaDoc) t);
127          else throw new RuntimeException JavaDoc(t);
128       }
129    }
130
131    public AttributeList JavaDoc getAttributes(String JavaDoc[] attributes)
132    {
133       AttributeList JavaDoc list = new AttributeList JavaDoc();
134
135       for (int i = 0; i < attributes.length; i++)
136       {
137          try
138          {
139             Object JavaDoc obj = getAttribute(attributes[i]);
140             list.add(new Attribute JavaDoc(attributes[i], obj));
141          }
142          catch (Exception JavaDoc e)
143          {
144             throw new RuntimeException JavaDoc("Error reading attribute: " + attributes[i], e);
145          }
146       }
147       return list;
148    }
149
150    public AttributeList JavaDoc setAttributes(AttributeList JavaDoc attributes)
151    {
152       for (Iterator JavaDoc it = attributes.iterator(); it.hasNext();)
153       {
154          Attribute JavaDoc attribute = (Attribute JavaDoc) it.next();
155          try
156          {
157             setAttribute(attribute);
158          }
159          catch (Exception JavaDoc e)
160          {
161             throw new RuntimeException JavaDoc("Error setting attribute: " + attribute, e);
162          }
163       }
164       return attributes;
165    }
166
167    public Object JavaDoc invoke(String JavaDoc actionName, Object JavaDoc params[], String JavaDoc signature[])
168            throws MBeanException JavaDoc, ReflectionException JavaDoc
169    {
170       if(log.isTraceEnabled())
171          log.trace("invoke: " + actionName);
172       
173       try
174       {
175          // EJBTHREE-655: intercept lifecycle methods
176
// if(isMagicLifecycleMethod(actionName))
177
// {
178
// invokeMagicLifecycleMethod(actionName);
179
// return null;
180
// }
181

182          Method JavaDoc operation = getOperation(actionName, signature);
183          return container.localInvoke(operation, params);
184       }
185       catch (Throwable JavaDoc t)
186       {
187          if (t instanceof Exception JavaDoc) throw new MBeanException JavaDoc((Exception JavaDoc) t);
188          else throw new RuntimeException JavaDoc(t);
189       }
190    }
191
192    public MBeanInfo JavaDoc getMBeanInfo()
193    {
194       return mbeanInfo;
195    }
196
197    private String JavaDoc getOperationSignature(String JavaDoc actionName, String JavaDoc[] types)
198    {
199       //Not really the signature, just something unique
200
StringBuffer JavaDoc sig = new StringBuffer JavaDoc();
201       sig.append(actionName);
202       
203       if (types != null)
204       {
205          for (int i = 0; i < types.length; i++)
206          {
207             sig.append(" ");
208             sig.append(types[i]);
209          }
210       }
211       return sig.toString();
212    }
213
214    private Method JavaDoc getGetter(String JavaDoc attribute) throws AttributeNotFoundException JavaDoc
215    {
216       Method JavaDoc getter = getterMethods.get(attribute);
217
218       if (getter == null && !getterBlackList.contains(attribute))
219       {
220          synchronized (getterMethods)
221          {
222             getter = getterMethods.get(attribute);
223             if (getter == null)
224             {
225                try
226                {
227                   MBeanAttributeInfo JavaDoc[] attrInfos = mbeanInfo.getAttributes();
228                   for (int i = 0; i < attrInfos.length; i++)
229                   {
230                      MBeanAttributeInfo JavaDoc attrInfo = attrInfos[i];
231                      if (attrInfo.getName().equals(attribute))
232                      {
233                         if (!attrInfo.isReadable())
234                         {
235                            throw new AttributeNotFoundException JavaDoc("Attribute '" + attribute + "' is not writable in " + container.getBeanClass().getName());
236                         }
237
238                         String JavaDoc getterName = ((attrInfo.isIs()) ? "is" : "get") + attribute;
239                         getter = container.getBeanClass().getMethod(getterName);
240                         getterMethods.put(attribute, getter);
241                      }
242                   }
243
244                   if (getter == null)
245                   {
246                      throw new AttributeNotFoundException JavaDoc("No attribute called '" + attribute + "' in " + container.getBeanClass());
247                   }
248                }
249                catch (NoSuchMethodException JavaDoc e)
250                {
251                   throw new AttributeNotFoundException JavaDoc("Could not find getter for attribute '" + attribute + "' on " + container.getBeanClass().getName());
252                }
253                finally
254                {
255                   if (getter == null)
256                   {
257                      getterBlackList.add(attribute);
258                   }
259                }
260             }
261          }
262       }
263
264       return getter;
265    }
266
267    private Method JavaDoc getSetter(Attribute JavaDoc attribute) throws AttributeNotFoundException JavaDoc
268    {
269       String JavaDoc attrName = attribute.getName();
270       Method JavaDoc setter = setterMethods.get(attrName);
271
272       if (setter == null && !setterBlackList.contains(attrName))
273       {
274          synchronized (setterMethods)
275          {
276             setter = setterMethods.get(attrName);
277             if (setter == null)
278             {
279                try
280                {
281                   MBeanAttributeInfo JavaDoc[] attrInfos = mbeanInfo.getAttributes();
282                   for (int i = 0; i < attrInfos.length; i++)
283                   {
284                      MBeanAttributeInfo JavaDoc attrInfo = attrInfos[i];
285                      if (attrInfo.getName().equals(attrName))
286                      {
287                         if (!attrInfo.isWritable())
288                         {
289                            throw new AttributeNotFoundException JavaDoc("Attribute '" + attrName + "' is not readable in " + container.getBeanClass().getName());
290                         }
291
292                         String JavaDoc setterName = "set" + attrName;
293                         Class JavaDoc type = Classes.loadClass(attrInfo.getType());
294                         setter = container.getBeanClass().getMethod(setterName, type);
295                         setterMethods.put(attrName, setter);
296                      }
297                   }
298
299                   if (setter == null)
300                   {
301                      throw new AttributeNotFoundException JavaDoc("No attribute called '" + attribute + "' in " + container.getBeanClass());
302                   }
303                }
304                catch (ClassNotFoundException JavaDoc e)
305                {
306                   throw new AttributeNotFoundException JavaDoc("Could not load setter type for attribute '" + attrName + "' on " + container.getBeanClass().getName());
307                }
308                catch (NoSuchMethodException JavaDoc e)
309                {
310                   throw new AttributeNotFoundException JavaDoc("Could not find setter for attribute '" + attrName + "' on " + container.getBeanClass().getName());
311                }
312                finally
313                {
314                   if (setter == null)
315                   {
316                      setterBlackList.add(attrName);
317                   }
318                }
319             }
320          }
321       }
322
323       return setter;
324    }
325
326    private Method JavaDoc getOperation(String JavaDoc actionName, String JavaDoc[] signature) throws ReflectionException JavaDoc
327    {
328       String JavaDoc opSig = getOperationSignature(actionName, signature);
329       Method JavaDoc operation = operations.get(actionName);
330
331       if (operation == null && !setterBlackList.contains(opSig))
332       {
333          synchronized (setterMethods)
334          {
335             operation = operations.get(opSig);
336             if (operation == null)
337             {
338                try
339                {
340                   MBeanOperationInfo JavaDoc[] opInfos = mbeanInfo.getOperations();
341                   for (int i = 0; i < opInfos.length; i++)
342                   {
343                      MBeanOperationInfo JavaDoc op = opInfos[i];
344                      if (op.getName().equals(actionName))
345                      {
346                         boolean match = true;
347                         MBeanParameterInfo JavaDoc[] sigTypes = op.getSignature();
348                         if (sigTypes.length == signature.length)
349                         {
350                            for (int j = 0; j < sigTypes.length; j++)
351                            {
352                               if (!sigTypes[j].getType().equals(signature[j]))
353                               {
354                                  match = false;
355                                  break;
356                               }
357                            }
358                         }
359
360                         if (match)
361                         {
362                            Class JavaDoc[] types = null;
363                            if (signature.length > 0)
364                            {
365                               types = new Class JavaDoc[signature.length];
366                               for (int j = 0; j < signature.length; j++)
367                               {
368                                  types[j] = Classes.loadClass(signature[j]);
369                               }
370                            }
371                            else
372                            {
373                               types = new Class JavaDoc[0];
374                            }
375                            operation = container.getBeanClass().getMethod(actionName, types);
376                            operations.put(opSig, operation);
377                         }
378                      }
379                   }
380
381                   if (operation == null)
382                   {
383                      throw new RuntimeException JavaDoc("No operation called '" + actionName + "' in " + container.getBeanClass());
384                   }
385
386                }
387                catch (ClassNotFoundException JavaDoc e)
388                {
389                   throw new RuntimeException JavaDoc("Could not find type for operation '" + actionName + "' on " + container.getBeanClass().getName());
390                }
391                catch (NoSuchMethodException JavaDoc e)
392                {
393                   throw new RuntimeException JavaDoc("Could not find method for operation '" + actionName + "' on " + container.getBeanClass().getName());
394                }
395                finally
396                {
397                   if (operation == null)
398                   {
399                      operationBlackList.add(opSig);
400                   }
401                }
402             }
403          }
404       }
405
406       return operation;
407    }
408
409    /* EJBTHREE-655 has been postponed
410    protected void invokeMagicLifecycleMethod(String operationName) throws Exception
411    {
412       if(operationName.equals("create"))
413          container.create();
414       else if(operationName.equals("start"))
415          container.start();
416       else if(operationName.equals("stop"))
417          container.stop();
418       else if(operationName.equals("destroy"))
419          container.destroy();
420       else
421          throw new IllegalArgumentException("can't invoke " + operationName);
422    }
423    
424    protected boolean isMagicLifecycleMethod(String methodName)
425    {
426       if(methodName.equals("create"))
427          return true;
428       if(methodName.equals("start"))
429          return true;
430       if(methodName.equals("stop"))
431          return true;
432       if(methodName.equals("destroy"))
433          return true;
434       return false;
435    }
436    */

437 }
438
Popular Tags