KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mx4j > server > ReflectionMBeanInvoker


1 /*
2  * Copyright (C) MX4J.
3  * All rights reserved.
4  *
5  * This software is distributed under the terms of the MX4J License version 1.0.
6  * See the terms of the MX4J License in the documentation provided with this software.
7  */

8
9 package mx4j.server;
10
11 import java.lang.reflect.InvocationTargetException JavaDoc;
12 import java.lang.reflect.Method JavaDoc;
13
14 import javax.management.Attribute JavaDoc;
15 import javax.management.AttributeNotFoundException JavaDoc;
16 import javax.management.InvalidAttributeValueException JavaDoc;
17 import javax.management.JMRuntimeException JavaDoc;
18 import javax.management.MBeanAttributeInfo JavaDoc;
19 import javax.management.MBeanException JavaDoc;
20 import javax.management.MBeanOperationInfo JavaDoc;
21 import javax.management.MBeanParameterInfo JavaDoc;
22 import javax.management.ReflectionException JavaDoc;
23 import javax.management.RuntimeErrorException JavaDoc;
24 import javax.management.RuntimeMBeanException JavaDoc;
25 import javax.management.RuntimeOperationsException JavaDoc;
26
27 import mx4j.util.Utils;
28 import mx4j.ImplementationException;
29
30 /**
31  * Stateless MBeanInvoker that uses reflection to invoke on MBean instances.
32  *
33  * @author <a HREF="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
34  * @version $Revision: 1.3 $
35  */

36 public class ReflectionMBeanInvoker implements MBeanInvoker
37 {
38    /**
39     * A zero-length String[] that indicates a parameterless signature of a method.
40     */

41    protected static final String JavaDoc[] EMPTY_PARAMS = new String JavaDoc[0];
42    /**
43     * A zero-length Object[] that indicates a parameterless argument list of a method
44     */

45    protected static final Object JavaDoc[] EMPTY_ARGS = new Object JavaDoc[0];
46
47    public Object JavaDoc invoke(MBeanMetaData metadata, String JavaDoc method, String JavaDoc[] params, Object JavaDoc[] args) throws MBeanException JavaDoc, ReflectionException JavaDoc
48    {
49       MBeanOperationInfo JavaDoc oper = getStandardOperationInfo(metadata, method, params);
50       if (oper != null)
51       {
52          try
53          {
54             return doInvoke(metadata, method, params, args);
55          }
56          catch (BadArgumentException x)
57          {
58             throw new RuntimeOperationsException JavaDoc(x.nested);
59          }
60       }
61       else
62       {
63          throw new ReflectionException JavaDoc(new NoSuchMethodException JavaDoc("Operation " + method + " does not belong to the management interface"));
64       }
65    }
66
67    public Object JavaDoc getAttribute(MBeanMetaData metadata, String JavaDoc attribute) throws MBeanException JavaDoc, AttributeNotFoundException JavaDoc, ReflectionException JavaDoc
68    {
69       MBeanAttributeInfo JavaDoc attr = getStandardAttributeInfo(metadata, attribute, false);
70       if (attr != null)
71       {
72          String JavaDoc methodName = getMethodForAttribute(attr, true);
73          try
74          {
75             return doInvoke(metadata, methodName, EMPTY_PARAMS, EMPTY_ARGS);
76          }
77          catch (BadArgumentException x)
78          {
79             // Never thrown, since there are no arguments
80
throw new ImplementationException();
81          }
82       }
83       else
84       {
85          throw new AttributeNotFoundException JavaDoc(attribute);
86       }
87    }
88
89    public void setAttribute(MBeanMetaData metadata, Attribute JavaDoc attribute) throws MBeanException JavaDoc, AttributeNotFoundException JavaDoc, InvalidAttributeValueException JavaDoc, ReflectionException JavaDoc
90    {
91       String JavaDoc name = attribute.getName();
92       MBeanAttributeInfo JavaDoc attr = getStandardAttributeInfo(metadata, name, true);
93       if (attr != null)
94       {
95          String JavaDoc methodName = getMethodForAttribute(attr, false);
96          try
97          {
98             doInvoke(metadata, methodName, new String JavaDoc[]{attr.getType()}, new Object JavaDoc[]{attribute.getValue()});
99          }
100          catch (BadArgumentException x)
101          {
102             throw new InvalidAttributeValueException JavaDoc("Invalid value for attribute " + name + ": " + attribute.getValue());
103          }
104       }
105       else
106       {
107          throw new AttributeNotFoundException JavaDoc(name);
108       }
109    }
110
111    /**
112     * Centralizes exception handling necessary to convert exceptions thrown by MBean's methods to
113     * JMX exceptions. Delegates the actual invocation to {@link #invokeImpl}
114     */

115    protected Object JavaDoc doInvoke(MBeanMetaData metadata, String JavaDoc method, String JavaDoc[] signature, Object JavaDoc[] args) throws ReflectionException JavaDoc, MBeanException JavaDoc, BadArgumentException
116    {
117       try
118       {
119          return invokeImpl(metadata, method, signature, args);
120       }
121       catch (ReflectionException JavaDoc x)
122       {
123          throw x;
124       }
125       catch (MBeanException JavaDoc x)
126       {
127          throw x;
128       }
129       catch (BadArgumentException x)
130       {
131          throw x;
132       }
133       catch (Throwable JavaDoc t)
134       {
135          if (t instanceof Error JavaDoc) throw new RuntimeErrorException JavaDoc((Error JavaDoc)t);
136          if (t instanceof JMRuntimeException JavaDoc) throw (JMRuntimeException JavaDoc)t;
137          if (t instanceof RuntimeException JavaDoc) throw new RuntimeMBeanException JavaDoc((RuntimeException JavaDoc)t);
138          throw new MBeanException JavaDoc((Exception JavaDoc)t);
139       }
140    }
141
142    /**
143     * Performs the actual invocation of the MBean's method.
144     * Exceptions thrown by the MBean's methods should not be catched, since {@link #doInvoke}
145     * takes care of converting them to JMX exceptions.
146     */

147    protected Object JavaDoc invokeImpl(MBeanMetaData metadata, String JavaDoc method, String JavaDoc[] signature, Object JavaDoc[] args) throws Throwable JavaDoc
148    {
149       Method JavaDoc m = getStandardManagementMethod(metadata, method, signature);
150       try
151       {
152          return m.invoke(metadata.getMBean(), args);
153       }
154       catch (IllegalAccessException JavaDoc x)
155       {
156          throw new ReflectionException JavaDoc(x);
157       }
158       catch (IllegalArgumentException JavaDoc x)
159       {
160          throw new BadArgumentException(x);
161       }
162       catch (InvocationTargetException JavaDoc x)
163       {
164          throw x.getTargetException();
165       }
166    }
167
168    /**
169     * Returns the MBeanOperationInfo for the given operation, or null if the operation
170     * is not a management operation.
171     */

172    protected MBeanOperationInfo JavaDoc getStandardOperationInfo(MBeanMetaData metadata, String JavaDoc method, String JavaDoc[] signature)
173    {
174       MBeanOperationInfo JavaDoc[] opers = metadata.getMBeanInfo().getOperations();
175       if (opers != null)
176       {
177          for (int i = 0; i < opers.length; ++i)
178          {
179             MBeanOperationInfo JavaDoc oper = opers[i];
180             String JavaDoc name = oper.getName();
181             if (method.equals(name))
182             {
183                // Same method name, check number of parameters
184
MBeanParameterInfo JavaDoc[] params = oper.getSignature();
185                if (signature.length == params.length)
186                {
187                   boolean match = true;
188                   for (int j = 0; j < params.length; ++j)
189                   {
190                      MBeanParameterInfo JavaDoc param = params[j];
191                      if (!signature[j].equals(param.getType()))
192                      {
193                         match = false;
194                         break;
195                      }
196                   }
197                   if (match) return oper;
198                }
199             }
200          }
201       }
202       return null;
203    }
204
205    /**
206     * Returns the MBeanAttributeInfo for the given attribute, or null if the attribute
207     * is not a management attribute.
208     */

209    protected MBeanAttributeInfo JavaDoc getStandardAttributeInfo(MBeanMetaData metadata, String JavaDoc attribute, boolean forWrite)
210    {
211       MBeanAttributeInfo JavaDoc[] attrs = metadata.getMBeanInfo().getAttributes();
212       if (attrs != null)
213       {
214          for (int i = 0; i < attrs.length; ++i)
215          {
216             MBeanAttributeInfo JavaDoc attr = attrs[i];
217             String JavaDoc name = attr.getName();
218             if (attribute.equals(name))
219             {
220                if (forWrite && attr.isWritable()) return attr;
221                if (!forWrite && attr.isReadable()) return attr;
222             }
223          }
224       }
225       return null;
226    }
227
228    /**
229     * Returns the method name for the given attribute.
230     */

231    protected String JavaDoc getMethodForAttribute(MBeanAttributeInfo JavaDoc attribute, boolean forRead)
232    {
233       String JavaDoc name = attribute.getName();
234       String JavaDoc attributeName = null;
235       if (forRead)
236       {
237          String JavaDoc prefix = attribute.isIs() ? "is" : "get";
238          attributeName = prefix + name;
239       }
240       else
241       {
242          attributeName = "set" + name;
243       }
244       return attributeName;
245    }
246
247    /**
248     * Returns a java.lang.reflect.Method object for the given method name and signature.
249     */

250    protected Method JavaDoc getStandardManagementMethod(MBeanMetaData metadata, String JavaDoc name, String JavaDoc[] signature) throws ReflectionException JavaDoc
251    {
252       try
253       {
254          Class JavaDoc[] params = Utils.loadClasses(metadata.getClassLoader(), signature);
255          Method JavaDoc method = metadata.getMBeanInterface().getMethod(name, params);
256          return method;
257       }
258       catch (ClassNotFoundException JavaDoc x)
259       {
260          throw new ReflectionException JavaDoc(x);
261       }
262       catch (NoSuchMethodException JavaDoc x)
263       {
264          throw new ReflectionException JavaDoc(x);
265       }
266    }
267
268    private static class BadArgumentException extends Exception JavaDoc
269    {
270       private final IllegalArgumentException JavaDoc nested;
271
272       private BadArgumentException(IllegalArgumentException JavaDoc nested)
273       {
274          this.nested = nested;
275       }
276    }
277 }
278
Popular Tags