1 /* BeanImpl.java - A common superclass for bean implementations.
2 Copyright (C) 2006 Free Software Foundation
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu.java.lang.management;
40 import gnu.javax.management.Translator;
42 import java.lang.management.ManagementPermission;
44 import java.lang.reflect.Array;
45 import java.lang.reflect.Method;
46 import java.lang.reflect.InvocationTargetException;
47 import java.util.ArrayList;
48 import java.util.Iterator;
49 import java.util.List;
53 import javax.management.AttributeNotFoundException;
54 import javax.management.MBeanAttributeInfo;
55 import javax.management.MBeanConstructorInfo;
56 import javax.management.MBeanException;
57 import javax.management.MBeanInfo;
58 import javax.management.MBeanOperationInfo;
59 import javax.management.MBeanParameterInfo;
60 import javax.management.NotCompliantMBeanException;
61 import javax.management.ReflectionException;
62 import javax.management.StandardMBean;
64 import javax.management.openmbean.ArrayType;
65 import javax.management.openmbean.CompositeDataSupport;
66 import javax.management.openmbean.CompositeType;
67 import javax.management.openmbean.OpenDataException;
68 import javax.management.openmbean.OpenMBeanAttributeInfo;
69 import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
70 import javax.management.openmbean.OpenMBeanConstructorInfo;
71 import javax.management.openmbean.OpenMBeanConstructorInfoSupport;
72 import javax.management.openmbean.OpenMBeanInfo;
73 import javax.management.openmbean.OpenMBeanInfoSupport;
74 import javax.management.openmbean.OpenMBeanOperationInfo;
75 import javax.management.openmbean.OpenMBeanOperationInfoSupport;
76 import javax.management.openmbean.OpenMBeanParameterInfo;
77 import javax.management.openmbean.OpenMBeanParameterInfoSupport;
78 import javax.management.openmbean.OpenType;
79 import javax.management.openmbean.TabularData;
80 import javax.management.openmbean.TabularDataSupport;
81 import javax.management.openmbean.TabularType;
84 * A common superclass for bean implementations.
86 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
94 * Cached open bean information.
96 private OpenMBeanInfo openInfo;
99 * Constructs a new <code>BeanImpl</code>.
101 * @param iface the bean interface being implemented.
102 * @throws NotCompliantMBeanException if this class doesn't implement
103 * the interface or a method appears
104 * in the interface that doesn't comply
105 * with the naming conventions.
107 protected BeanImpl(Class iface)
108 throws NotCompliantMBeanException
113 protected void cacheMBeanInfo(MBeanInfo info)
119 MBeanAttributeInfo[] oldA = info.getAttributes();
120 OpenMBeanAttributeInfo[] attribs =
121 new OpenMBeanAttributeInfoSupport[oldA.length];
122 for (int a = 0; a < oldA.length; ++a)
124 OpenMBeanParameterInfo param = Translator.translate(oldA[a].getType());
125 if (param.getMinValue() == null)
128 if (param.getLegalValues() == null)
131 lv = param.getLegalValues().toArray();
132 attribs[a] = new OpenMBeanAttributeInfoSupport(oldA[a].getName(),
133 oldA[a].getDescription(),
135 param.getOpenType()),
136 oldA[a].isReadable(),
137 oldA[a].isWritable(),
139 param.getDefaultValue(),
143 attribs[a] = new OpenMBeanAttributeInfoSupport(oldA[a].getName(),
144 oldA[a].getDescription(),
146 param.getOpenType()),
147 oldA[a].isReadable(),
148 oldA[a].isWritable(),
150 param.getDefaultValue(),
151 ((Comparable<Object>)
152 param.getMinValue()),
153 ((Comparable<Object>)
154 param.getMaxValue()));
156 MBeanConstructorInfo[] oldC = info.getConstructors();
157 OpenMBeanConstructorInfo[] cons = new OpenMBeanConstructorInfoSupport[oldC.length];
158 for (int a = 0; a < oldC.length; ++a)
160 new OpenMBeanConstructorInfoSupport(oldC[a].getName(),
161 oldC[a].getDescription(),
162 translateSignature(oldC[a].getSignature()));
163 MBeanOperationInfo[] oldO = info.getOperations();
164 OpenMBeanOperationInfo[] ops = new OpenMBeanOperationInfoSupport[oldO.length];
165 for (int a = 0; a < oldO.length; ++a)
167 new OpenMBeanOperationInfoSupport(oldO[a].getName(),
168 oldO[a].getDescription(),
169 translateSignature(oldO[a].getSignature()),
170 Translator.translate(oldO[a].getReturnType()).getOpenType(),
171 oldO[a].getImpact());
172 openInfo = new OpenMBeanInfoSupport(info.getClassName(), info.getDescription(),
173 attribs, cons, ops, info.getNotifications());
175 catch (OpenDataException e)
177 throw (InternalError) (new InternalError("A problem occurred creating the open type " +
178 "descriptors.").initCause(e));
182 protected void checkMonitorPermissions()
184 SecurityManager sm = System.getSecurityManager();
186 sm.checkPermission(new ManagementPermission("monitor"));
189 protected void checkControlPermissions()
191 SecurityManager sm = System.getSecurityManager();
193 sm.checkPermission(new ManagementPermission("control"));
196 public Object getAttribute(String attribute)
197 throws AttributeNotFoundException, MBeanException,
200 Object value = super.getAttribute(attribute);
201 if (value instanceof Enum)
202 return ((Enum) value).name();
203 Class vClass = value.getClass();
204 if (vClass.isArray())
205 vClass = vClass.getComponentType();
206 String cName = vClass.getName();
207 String[] allowedTypes = OpenType.ALLOWED_CLASSNAMES;
208 for (int a = 0; a < allowedTypes.length; ++a)
209 if (cName.equals(allowedTypes[a]))
211 OpenMBeanInfo info = (OpenMBeanInfo) getMBeanInfo();
212 MBeanAttributeInfo[] attribs =
213 (MBeanAttributeInfo[]) info.getAttributes();
214 OpenType type = null;
215 for (int a = 0; a < attribs.length; ++a)
216 if (attribs[a].getName().equals(attribute))
217 type = ((OpenMBeanAttributeInfo) attribs[a]).getOpenType();
218 if (value instanceof List)
223 Class.forName(((ArrayType) type).getElementOpenType().getClassName());
224 List l = (List) value;
225 Object[] array = (Object[]) Array.newInstance(e, l.size());
226 return l.toArray(array);
228 catch (ClassNotFoundException e)
230 throw (InternalError) (new InternalError("The class of the list " +
231 "element type could not " +
232 "be created").initCause(e));
235 if (value instanceof Map)
237 TabularType ttype = (TabularType) type;
238 TabularData data = new TabularDataSupport(ttype);
239 Iterator it = ((Map) value).entrySet().iterator();
242 Map.Entry entry = (Map.Entry) it.next();
245 data.put(new CompositeDataSupport(ttype.getRowType(),
255 catch (OpenDataException e)
257 throw (InternalError) (new InternalError("A problem occurred " +
258 "converting the map " +
259 "to a composite data " +
260 "structure.").initCause(e));
265 CompositeType cType = (CompositeType) type;
266 Set names = cType.keySet();
267 Iterator it = names.iterator();
268 List values = new ArrayList(names.size());
271 String field = (String) it.next();
272 Method getter = null;
275 getter = vClass.getMethod("get" + field);
277 catch (NoSuchMethodException e)
279 /* Ignored; the type tells us it's there. */
283 values.add(getter.invoke(value));
285 catch (IllegalAccessException e)
287 throw new ReflectionException(e, "Failed to retrieve " + field);
289 catch (IllegalArgumentException e)
291 throw new ReflectionException(e, "Failed to retrieve " + field);
293 catch (InvocationTargetException e)
295 throw new MBeanException((Exception) e.getCause(),
296 "The getter of " + field +
297 " threw an exception");
302 return new CompositeDataSupport(cType,
304 names.toArray(new String[names.size()]),
307 catch (OpenDataException e)
309 throw (InternalError) (new InternalError("A problem occurred " +
310 "converting the value " +
311 "to a composite data " +
312 "structure.").initCause(e));
316 protected MBeanInfo getCachedMBeanInfo()
318 return (MBeanInfo) openInfo;
322 * Override this method so as to prevent the description of a constructor's
323 * parameter being @code{null}. Open MBeans can not have @code{null} descriptions,
324 * but one will occur as the names of parameters aren't stored for reflection.
326 * @param constructor the constructor whose parameter needs describing.
327 * @param parameter the parameter to be described.
328 * @param sequenceNo the number of the parameter to describe.
329 * @return a description of the constructor's parameter.
331 protected String getDescription(MBeanConstructorInfo constructor,
332 MBeanParameterInfo parameter,
335 String desc = parameter.getDescription();
337 return "param" + sequenceNo;
343 * Override this method so as to prevent the description of an operation's
344 * parameter being @code{null}. Open MBeans can not have @code{null} descriptions,
345 * but one will occur as the names of parameters aren't stored for reflection.
347 * @param operation the operation whose parameter needs describing.
348 * @param parameter the parameter to be described.
349 * @param sequenceNo the number of the parameter to describe.
350 * @return a description of the operation's parameter.
352 protected String getDescription(MBeanOperationInfo operation,
353 MBeanParameterInfo parameter,
356 String desc = parameter.getDescription();
358 return "param" + sequenceNo;
364 * Override this method so as to prevent the name of a constructor's
365 * parameter being @code{null}. Open MBeans can not have @code{null} names,
366 * but one will occur as the names of parameters aren't stored for reflection.
368 * @param constructor the constructor whose parameter needs a name.
369 * @param parameter the parameter to be named.
370 * @param sequenceNo the number of the parameter to name.
371 * @return a description of the constructor's parameter.
373 protected String getParameterName(MBeanConstructorInfo constructor,
374 MBeanParameterInfo parameter,
377 String name = parameter.getName();
379 return "param" + sequenceNo;
385 * Override this method so as to prevent the name of an operation's
386 * parameter being @code{null}. Open MBeans can not have @code{null} names,
387 * but one will occur as the names of parameters aren't stored for reflection.
389 * @param operation the operation whose parameter needs a name.
390 * @param parameter the parameter to be named.
391 * @param sequenceNo the number of the parameter to name.
392 * @return a description of the operation's parameter.
394 protected String getParameterName(MBeanOperationInfo operation,
395 MBeanParameterInfo parameter,
398 String name = parameter.getName();
400 return "param" + sequenceNo;
405 public MBeanInfo getMBeanInfo()
407 super.getMBeanInfo();
408 return getCachedMBeanInfo();
411 private OpenMBeanParameterInfo[] translateSignature(MBeanParameterInfo[] oldS)
412 throws OpenDataException
414 OpenMBeanParameterInfo[] sig = new OpenMBeanParameterInfoSupport[oldS.length];
415 for (int a = 0; a < oldS.length; ++a)
417 OpenMBeanParameterInfo param = Translator.translate(oldS[a].getType());
418 if (param.getMinValue() == null)
421 if (param.getLegalValues() == null)
424 lv = param.getLegalValues().toArray();
425 sig[a] = new OpenMBeanParameterInfoSupport(oldS[a].getName(),
426 oldS[a].getDescription(),
428 param.getOpenType()),
429 param.getDefaultValue(),
433 sig[a] = new OpenMBeanParameterInfoSupport(oldS[a].getName(),
434 oldS[a].getDescription(),
436 param.getOpenType()),
437 param.getDefaultValue(),
438 ((Comparable<Object>)
439 param.getMinValue()),
440 ((Comparable<Object>)
441 param.getMaxValue()));