summaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/javax/management
diff options
context:
space:
mode:
authorupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
committerupstream source tree <ports@midipix.org>2015-03-15 20:14:05 -0400
commit554fd8c5195424bdbcabf5de30fdc183aba391bd (patch)
tree976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/gnu/javax/management
downloadcbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2
cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository.
Diffstat (limited to 'libjava/classpath/gnu/javax/management')
-rw-r--r--libjava/classpath/gnu/javax/management/ListenerData.java136
-rw-r--r--libjava/classpath/gnu/javax/management/Server.java2233
-rw-r--r--libjava/classpath/gnu/javax/management/Translator.java550
3 files changed, 2919 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/javax/management/ListenerData.java b/libjava/classpath/gnu/javax/management/ListenerData.java
new file mode 100644
index 000000000..31fdeccf0
--- /dev/null
+++ b/libjava/classpath/gnu/javax/management/ListenerData.java
@@ -0,0 +1,136 @@
+/* ListenerData.java - Class to contain data about management bean listeners
+ Copyright (C) 2006 Free Software Foundation
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.management;
+
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+
+/**
+ * Container for data on management listeners. Wraps
+ * a {@link javax.management.NotificationListener},
+ * {@link javax.management.NotificationFilter} and
+ * passback object in one class.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class ListenerData
+{
+ /**
+ * The listener itself.
+ */
+ private NotificationListener listener;
+
+ /**
+ * A filter to apply to incoming events.
+ */
+ private NotificationFilter filter;
+
+ /**
+ * An object to pass back to the listener on an
+ * event occurring.
+ */
+ private Object passback;
+
+ /**
+ * Constructs a new {@link ListenerData} with the specified
+ * listener, filter and passback object.
+ *
+ * @param listener the listener itself.
+ * @param filter the filter for incoming events.
+ * @param passback the object to passback on an incoming event.
+ */
+ public ListenerData(NotificationListener listener,
+ NotificationFilter filter, Object passback)
+ {
+ this.listener = listener;
+ this.filter = filter;
+ this.passback = passback;
+ }
+
+ /**
+ * Returns the listener.
+ *
+ * @return the listener.
+ */
+ public NotificationListener getListener()
+ {
+ return listener;
+ }
+
+ /**
+ * Returns the filter.
+ *
+ * @return the filter.
+ */
+ public NotificationFilter getFilter()
+ {
+ return filter;
+ }
+
+ /**
+ * Returns the passback object.
+ *
+ * @return the passback object.
+ */
+ public Object getPassback()
+ {
+ return passback;
+ }
+
+ /**
+ * Returns true if the supplied object is an instance of
+ * {@link ListenerData} and has the same listener, filter
+ * and passback object.
+ *
+ * @param obj the object to check.
+ * @return true if <code>obj</code> is equal to this.
+ */
+ public boolean equals(Object obj)
+ {
+ if (obj instanceof ListenerData)
+ {
+ ListenerData data = (ListenerData) obj;
+ return (data.getListener() == listener &&
+ data.getFilter() == filter &&
+ data.getPassback() == passback);
+ }
+ return false;
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/management/Server.java b/libjava/classpath/gnu/javax/management/Server.java
new file mode 100644
index 000000000..50252d4dd
--- /dev/null
+++ b/libjava/classpath/gnu/javax/management/Server.java
@@ -0,0 +1,2233 @@
+/* Server.java -- A GNU Classpath management server.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.management;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.io.StreamCorruptedException;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.BadAttributeValueExpException;
+import javax.management.BadBinaryOpValueExpException;
+import javax.management.BadStringOperationException;
+import javax.management.DynamicMBean;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.InvalidApplicationException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MalformedObjectNameException;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanPermission;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerDelegate;
+import javax.management.MBeanServerNotification;
+import javax.management.MBeanTrustPermission;
+import javax.management.NotCompliantMBeanException;
+import javax.management.Notification;
+import javax.management.NotificationBroadcaster;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import javax.management.OperationsException;
+import javax.management.QueryExp;
+import javax.management.ReflectionException;
+import javax.management.RuntimeOperationsException;
+import javax.management.StandardMBean;
+
+import javax.management.loading.ClassLoaderRepository;
+
+/**
+ * This class provides an {@link javax.management.MBeanServer}
+ * implementation for GNU Classpath.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ * @since 1.5
+ */
+public class Server
+ implements MBeanServer
+{
+
+ /**
+ * The name of the delegate bean.
+ */
+ private static final ObjectName DELEGATE_NAME;
+
+ /**
+ * The registered beans, represented as a map of
+ * {@link javax.management.ObjectName}s to
+ * {@link gnu.javax.management.Server.ServerInfo}s.
+ */
+ private final ConcurrentHashMap<ObjectName,ServerInfo> beans =
+ new ConcurrentHashMap<ObjectName,ServerInfo>();
+
+ /**
+ * The default domain.
+ */
+ private final String defaultDomain;
+
+ /**
+ * The outer server.
+ */
+ private final MBeanServer outer;
+
+ /**
+ * The class loader repository.
+ */
+ private ClassLoaderRepository repository;
+
+ /**
+ * The map of listener delegates to the true
+ * listener. We wrap this in an inner class
+ * to delay initialisation until a listener
+ * is actually added.
+ */
+ private static class LazyListenersHolder
+ {
+ private static final Map<NotificationListener,NotificationListener> listeners =
+ new ConcurrentHashMap<NotificationListener,NotificationListener>();
+ }
+
+ /**
+ * An MBean that emits notifications when an MBean is registered and
+ * unregistered with this server.
+ *
+ */
+ private final MBeanServerDelegate delegate;
+
+ /**
+ * Provides sequencing for notifications about registrations.
+ */
+ private static final AtomicLong sequenceNumber = new AtomicLong(1);
+
+ /**
+ * Initialise the delegate name.
+ */
+ static
+ {
+ try
+ {
+ DELEGATE_NAME =
+ new ObjectName("JMImplementation:type=MBeanServerDelegate");
+ }
+ catch (MalformedObjectNameException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to construct " +
+ "the delegate's object name.").initCause(e));
+ }
+ }
+
+ /**
+ * Constructs a new management server using the specified
+ * default domain, delegate bean and outer server.
+ *
+ * @param defaultDomain the default domain to use for beans constructed
+ * with no specified domain.
+ * @param outer an {@link javax.management.MBeanServer} to pass
+ * to beans implementing the {@link MBeanRegistration}
+ * interface, or <code>null</code> if <code>this</code>
+ * should be passed.
+ * @param delegate the delegate bean for this server.
+ */
+ public Server(String defaultDomain, MBeanServer outer,
+ MBeanServerDelegate delegate)
+ {
+ this.defaultDomain = defaultDomain;
+ this.outer = outer;
+ this.delegate = delegate;
+ try
+ {
+ registerMBean(delegate, DELEGATE_NAME);
+ }
+ catch (InstanceAlreadyExistsException e)
+ {
+ throw (Error)
+ (new InternalError("The delegate bean is " +
+ "already registered.").initCause(e));
+ }
+ catch (MBeanRegistrationException e)
+ {
+ throw (Error)
+ (new InternalError("The delegate bean's preRegister " +
+ "methods threw an exception.").initCause(e));
+ }
+ catch (NotCompliantMBeanException e)
+ {
+ throw (Error)
+ (new InternalError("The delegate bean is " +
+ "not compliant.").initCause(e));
+ }
+ }
+
+ /**
+ * Checks for the necessary security privileges to perform an
+ * operation.
+ *
+ * @param name the name of the bean being accessed.
+ * @param member the name of the operation or attribute being
+ * accessed, or <code>null</code> if one is not
+ * involved.
+ * @param action the action being performed.
+ * @throws SecurityException if the action is denied.
+ */
+ private void checkSecurity(ObjectName name, String member,
+ String action)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ try
+ {
+ MBeanInfo info = null;
+ if (name != null)
+ {
+ Object bean = getBean(name);
+ Method method = bean.getClass().getMethod("getMBeanInfo");
+ info = (MBeanInfo) method.invoke(bean);
+ }
+ sm.checkPermission(new MBeanPermission((info == null) ?
+ null : info.getClassName(),
+ member, name, action));
+ }
+ catch (InstanceNotFoundException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to get bean.").initCause(e));
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to get bean info.").initCause(e));
+ }
+ catch (IllegalAccessException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to get bean info.").initCause(e));
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to get bean info.").initCause(e));
+ }
+ catch (InvocationTargetException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to get bean info.").initCause(e));
+ }
+ }
+
+ /**
+ * Retrieves the specified bean.
+ *
+ * @param name the name of the bean.
+ * @return the bean.
+ * @throws InstanceNotFoundException if the name of the management bean
+ * could not be resolved.
+ */
+ private Object getBean(ObjectName name)
+ throws InstanceNotFoundException
+ {
+ ServerInfo bean = beans.get(name);
+ if (bean == null)
+ throw new InstanceNotFoundException("The bean, " + name +
+ ", was not found.");
+ return bean.getObject();
+ }
+
+ /**
+ * Registers the supplied listener with the specified management
+ * bean. Notifications emitted by the management bean are forwarded
+ * to the listener via the server, which will convert an MBean
+ * references in the source to a portable {@link ObjectName}
+ * instance. The notification is otherwise unchanged.
+ *
+ * @param name the name of the management bean with which the listener
+ * should be registered.
+ * @param listener the listener which will handle notifications from
+ * the bean.
+ * @param filter the filter to apply to incoming notifications, or
+ * <code>null</code> if no filtering should be applied.
+ * @param passback an object to be passed to the listener when a
+ * notification is emitted.
+ * @throws InstanceNotFoundException if the name of the management bean
+ * could not be resolved.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "addNotificationListener")</code>}.
+ * @see #removeNotificationListener(ObjectName, NotificationListener)
+ * @see #removeNotificationListener(ObjectName, NotificationListener,
+ * NotificationFilter, Object)
+ * @see NotificationBroadcaster#addNotificationListener(NotificationListener,
+ * NotificationFilter,
+ * Object)
+ */
+ public void addNotificationListener(ObjectName name, NotificationListener listener,
+ NotificationFilter filter, Object passback)
+ throws InstanceNotFoundException
+ {
+ Object bean = getBean(name);
+ checkSecurity(name, null, "addNotificationListener");
+ if (bean instanceof NotificationBroadcaster)
+ {
+ NotificationBroadcaster bbean = (NotificationBroadcaster) bean;
+ NotificationListener indirection = new ServerNotificationListener(bean, name,
+ listener);
+ bbean.addNotificationListener(indirection, filter, passback);
+ LazyListenersHolder.listeners.put(listener, indirection);
+ }
+ }
+
+ /**
+ * <p>
+ * Registers the supplied listener with the specified management
+ * bean. Notifications emitted by the management bean are forwarded
+ * to the listener via the server, which will convert any MBean
+ * references in the source to portable {@link ObjectName}
+ * instances. The notification is otherwise unchanged.
+ * </p>
+ * <p>
+ * The listener that receives notifications will be the one that is
+ * registered with the given name at the time this method is called.
+ * Even if it later unregisters and ceases to use that name, it will
+ * still receive notifications.
+ * </p>
+ *
+ * @param name the name of the management bean with which the listener
+ * should be registered.
+ * @param listener the name of the listener which will handle
+ * notifications from the bean.
+ * @param filter the filter to apply to incoming notifications, or
+ * <code>null</code> if no filtering should be applied.
+ * @param passback an object to be passed to the listener when a
+ * notification is emitted.
+ * @throws InstanceNotFoundException if the name of the management bean
+ * could not be resolved.
+ * @throws RuntimeOperationsException if the bean associated with the given
+ * object name is not a
+ * {@link NotificationListener}. This
+ * exception wraps an
+ * {@link IllegalArgumentException}.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "addNotificationListener")</code>}.
+ * @see #removeNotificationListener(ObjectName, NotificationListener)
+ * @see #removeNotificationListener(ObjectName, NotificationListener,
+ * NotificationFilter, Object)
+ * @see NotificationBroadcaster#addNotificationListener(NotificationListener,
+ * NotificationFilter,
+ * Object)
+ */
+ public void addNotificationListener(ObjectName name, ObjectName listener,
+ NotificationFilter filter, Object passback)
+ throws InstanceNotFoundException
+ {
+ Object lbean = getBean(listener);
+ if (!(lbean instanceof NotificationListener))
+ {
+ RuntimeException e =
+ new IllegalArgumentException("The supplied listener name does not " +
+ "correspond to a notification listener.");
+ throw new RuntimeOperationsException(e);
+ }
+ addNotificationListener(name, ((NotificationListener) lbean), filter, passback);
+ }
+
+ /**
+ * <p>
+ * Instantiates a new instance of the specified management bean
+ * using the default constructor and registers it with the server
+ * under the supplied name. The class is loaded using the
+ * {@link javax.management.loading.ClassLoaderRepository default
+ * loader repository} of the server.
+ * </p>
+ * <p>
+ * If the name supplied is <code>null</code>, then the bean is
+ * expected to implement the {@link MBeanRegistration} interface.
+ * The {@link MBeanRegistration#preRegister preRegister} method
+ * of this interface will be used to obtain the name in this case.
+ * </p>
+ * <p>
+ * This method is equivalent to calling {@link
+ * #createMBean(String, ObjectName, Object[], String[])
+ * <code>createMBean(className, name, (Object[]) null,
+ * (String[]) null)</code>} with <code>null</code> parameters
+ * and signature.
+ * </p>
+ *
+ * @param className the class of the management bean, of which
+ * an instance should be created.
+ * @param name the name to register the new bean with.
+ * @return an {@link ObjectInstance} containing the {@link ObjectName}
+ * and Java class name of the created instance.
+ * @throws ReflectionException if an exception occurs in creating
+ * an instance of the bean.
+ * @throws InstanceAlreadyExistsException if a matching instance
+ * already exists.
+ * @throws MBeanRegistrationException if an exception occurs in
+ * calling the preRegister
+ * method.
+ * @throws MBeanException if the bean's constructor throws an exception.
+ * @throws NotCompliantMBeanException if the created bean is not
+ * compliant with the JMX specification.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> class name or object
+ * name or if the object name is a pattern.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply the
+ * use of the <code>instantiate</code>
+ * and <code>registerMBean</code> methods.
+ * @see #createMBean(String, ObjectName, Object[], String[])
+ */
+ public ObjectInstance createMBean(String className, ObjectName name)
+ throws ReflectionException, InstanceAlreadyExistsException,
+ MBeanRegistrationException, MBeanException,
+ NotCompliantMBeanException
+ {
+ return createMBean(className, name, (Object[]) null, (String[]) null);
+ }
+
+ /**
+ * <p>
+ * Instantiates a new instance of the specified management bean
+ * using the given constructor and registers it with the server
+ * under the supplied name. The class is loaded using the
+ * {@link javax.management.loading.ClassLoaderRepository default
+ * loader repository} of the server.
+ * </p>
+ * <p>
+ * If the name supplied is <code>null</code>, then the bean is
+ * expected to implement the {@link MBeanRegistration} interface.
+ * The {@link MBeanRegistration#preRegister preRegister} method
+ * of this interface will be used to obtain the name in this case.
+ * </p>
+ *
+ * @param className the class of the management bean, of which
+ * an instance should be created.
+ * @param name the name to register the new bean with.
+ * @param params the parameters for the bean's constructor.
+ * @param sig the signature of the constructor to use.
+ * @return an {@link ObjectInstance} containing the {@link ObjectName}
+ * and Java class name of the created instance.
+ * @throws ReflectionException if an exception occurs in creating
+ * an instance of the bean.
+ * @throws InstanceAlreadyExistsException if a matching instance
+ * already exists.
+ * @throws MBeanRegistrationException if an exception occurs in
+ * calling the preRegister
+ * method.
+ * @throws MBeanException if the bean's constructor throws an exception.
+ * @throws NotCompliantMBeanException if the created bean is not
+ * compliant with the JMX specification.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> class name or object
+ * name or if the object name is a pattern.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply the
+ * use of the <code>instantiate</code>
+ * and <code>registerMBean</code> methods.
+ */
+ public ObjectInstance createMBean(String className, ObjectName name,
+ Object[] params, String[] sig)
+ throws ReflectionException, InstanceAlreadyExistsException,
+ MBeanRegistrationException, MBeanException,
+ NotCompliantMBeanException
+ {
+ return registerMBean(instantiate(className, params, sig), name);
+ }
+
+ /**
+ * <p>
+ * Instantiates a new instance of the specified management bean
+ * using the default constructor and registers it with the server
+ * under the supplied name. The class is loaded using the
+ * given class loader. If this argument is <code>null</code>,
+ * then the same class loader as was used to load the server
+ * is used.
+ * </p>
+ * <p>
+ * If the name supplied is <code>null</code>, then the bean is
+ * expected to implement the {@link MBeanRegistration} interface.
+ * The {@link MBeanRegistration#preRegister preRegister} method
+ * of this interface will be used to obtain the name in this case.
+ * </p>
+ * <p>
+ * This method is equivalent to calling {@link
+ * #createMBean(String, ObjectName, ObjectName, Object[], String)
+ * <code>createMBean(className, name, loaderName, (Object[]) null,
+ * (String) null)</code>} with <code>null</code> parameters
+ * and signature.
+ * </p>
+ *
+ * @param className the class of the management bean, of which
+ * an instance should be created.
+ * @param name the name to register the new bean with.
+ * @param loaderName the name of the class loader.
+ * @return an {@link ObjectInstance} containing the {@link ObjectName}
+ * and Java class name of the created instance.
+ * @throws ReflectionException if an exception occurs in creating
+ * an instance of the bean.
+ * @throws InstanceAlreadyExistsException if a matching instance
+ * already exists.
+ * @throws MBeanRegistrationException if an exception occurs in
+ * calling the preRegister
+ * method.
+ * @throws MBeanException if the bean's constructor throws an exception.
+ * @throws NotCompliantMBeanException if the created bean is not
+ * compliant with the JMX specification.
+ * @throws InstanceNotFoundException if the specified class loader is not
+ * registered with the server.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> class name or object
+ * name or if the object name is a pattern.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply the
+ * use of the <code>instantiate</code>
+ * and <code>registerMBean</code> methods.
+ * @see #createMBean(String, ObjectName, ObjectName, Object[], String[])
+ */
+ public ObjectInstance createMBean(String className, ObjectName name,
+ ObjectName loaderName)
+ throws ReflectionException, InstanceAlreadyExistsException,
+ MBeanRegistrationException, MBeanException,
+ NotCompliantMBeanException, InstanceNotFoundException
+ {
+ return createMBean(className, name, loaderName, (Object[]) null,
+ (String[]) null);
+ }
+
+ /**
+ * <p>
+ * Instantiates a new instance of the specified management bean
+ * using the given constructor and registers it with the server
+ * under the supplied name. The class is loaded using the
+ * given class loader. If this argument is <code>null</code>,
+ * then the same class loader as was used to load the server
+ * is used.
+ * </p>
+ * <p>
+ * If the name supplied is <code>null</code>, then the bean is
+ * expected to implement the {@link MBeanRegistration} interface.
+ * The {@link MBeanRegistration#preRegister preRegister} method
+ * of this interface will be used to obtain the name in this case.
+ * </p>
+ *
+ * @param className the class of the management bean, of which
+ * an instance should be created.
+ * @param name the name to register the new bean with.
+ * @param loaderName the name of the class loader.
+ * @param params the parameters for the bean's constructor.
+ * @param sig the signature of the constructor to use.
+ * @return an {@link ObjectInstance} containing the {@link ObjectName}
+ * and Java class name of the created instance.
+ * @throws ReflectionException if an exception occurs in creating
+ * an instance of the bean.
+ * @throws InstanceAlreadyExistsException if a matching instance
+ * already exists.
+ * @throws MBeanRegistrationException if an exception occurs in
+ * calling the preRegister
+ * method.
+ * @throws MBeanException if the bean's constructor throws an exception.
+ * @throws NotCompliantMBeanException if the created bean is not
+ * compliant with the JMX specification.
+ * @throws InstanceNotFoundException if the specified class loader is not
+ * registered with the server.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> class name or object
+ * name or if the object name is a pattern.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply the
+ * use of the <code>instantiate</code>
+ * and <code>registerMBean</code> methods.
+ */
+ public ObjectInstance createMBean(String className, ObjectName name,
+ ObjectName loaderName, Object[] params,
+ String[] sig)
+ throws ReflectionException, InstanceAlreadyExistsException,
+ MBeanRegistrationException, MBeanException,
+ NotCompliantMBeanException, InstanceNotFoundException
+ {
+ return registerMBean(instantiate(className, loaderName, params, sig),
+ name);
+ }
+
+ /**
+ * Deserializes a byte array using the class loader of the specified
+ * management bean as its context.
+ *
+ * @param name the name of the bean whose class loader should be used.
+ * @param data the byte array to be deserialized.
+ * @return the deserialized object stream.
+ * @deprecated {@link #getClassLoaderFor(ObjectName)} should be used
+ * to obtain the class loader of the bean, which can then
+ * be used to perform deserialization in the user's code.
+ * @throws InstanceNotFoundException if the specified bean is not
+ * registered with the server.
+ * @throws OperationsException if any I/O error is thrown by the
+ * deserialization process.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "getClassLoaderFor")</code>
+ */
+ public ObjectInputStream deserialize(ObjectName name, byte[] data)
+ throws InstanceNotFoundException, OperationsException
+ {
+ try
+ {
+ return new ServerInputStream(new ByteArrayInputStream(data),
+ getClassLoaderFor(name));
+ }
+ catch (IOException e)
+ {
+ throw new OperationsException("An I/O error occurred: " + e);
+ }
+ }
+
+ /**
+ * Deserializes a byte array using the same class loader for its context
+ * as was used to load the given class. This class loader is obtained by
+ * loading the specified class using the {@link
+ * javax.management.loading.ClassLoaderRepository Class Loader Repository}
+ * and then using the class loader of the resulting {@link Class} instance.
+ *
+ * @param name the name of the class which should be loaded to obtain the
+ * class loader.
+ * @param data the byte array to be deserialized.
+ * @return the deserialized object stream.
+ * @deprecated {@link #getClassLoaderRepository} should be used
+ * to obtain the class loading repository, which can then
+ * be used to obtain the {@link Class} instance and deserialize
+ * the array using its class loader.
+ * @throws OperationsException if any I/O error is thrown by the
+ * deserialization process.
+ * @throws ReflectionException if an error occurs in obtaining the
+ * {@link Class} instance.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(null, null, null,
+ * "getClassLoaderRepository")</code>
+ */
+ public ObjectInputStream deserialize(String name, byte[] data)
+ throws OperationsException, ReflectionException
+ {
+ try
+ {
+ Class<?> c = getClassLoaderRepository().loadClass(name);
+ return new ServerInputStream(new ByteArrayInputStream(data),
+ c.getClassLoader());
+ }
+ catch (IOException e)
+ {
+ throw new OperationsException("An I/O error occurred: " + e);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new ReflectionException(e, "The class could not be found.");
+ }
+ }
+
+ /**
+ * Deserializes a byte array using the same class loader for its context
+ * as was used to load the given class. The name of the class loader to
+ * be used is supplied, and may be <code>null</code> if the server's
+ * class loader should be used instead.
+ *
+ * @param name the name of the class which should be loaded to obtain the
+ * class loader.
+ * @param loader the name of the class loader to use, or <code>null</code>
+ * if the class loader of the server should be used.
+ * @param data the byte array to be deserialized.
+ * @return the deserialized object stream.
+ * @deprecated {@link #getClassLoader(ObjectName} can be used to obtain
+ * the named class loader and deserialize the array.
+ * @throws InstanceNotFoundException if the specified class loader is not
+ * registered with the server.
+ * @throws OperationsException if any I/O error is thrown by the
+ * deserialization process.
+ * @throws ReflectionException if an error occurs in obtaining the
+ * {@link Class} instance.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, loader,
+ * "getClassLoader")</code>
+ */
+ public ObjectInputStream deserialize(String name, ObjectName loader, byte[] data)
+ throws InstanceNotFoundException, ReflectionException,
+ OperationsException
+ {
+ try
+ {
+ Class<?> c = getClassLoader(loader).loadClass(name);
+ return new ServerInputStream(new ByteArrayInputStream(data),
+ c.getClassLoader());
+ }
+ catch (IOException e)
+ {
+ throw new OperationsException("An I/O error occurred: " + e);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new ReflectionException(e, "The class could not be found.");
+ }
+ }
+
+ /**
+ * Returns the value of the supplied attribute from the specified
+ * management bean.
+ *
+ * @param bean the bean to retrieve the value from.
+ * @param name the name of the attribute to retrieve.
+ * @return the value of the attribute.
+ * @throws AttributeNotFoundException if the attribute could not be
+ * accessed from the bean.
+ * @throws MBeanException if the management bean's accessor throws
+ * an exception.
+ * @throws InstanceNotFoundException if the bean can not be found.
+ * @throws ReflectionException if an exception was thrown in trying
+ * to invoke the bean's accessor.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> bean or attribute
+ * name.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, name, bean,
+ * "getAttribute")</code>}.
+ * @see DynamicMBean#getAttribute(String)
+ */
+ public Object getAttribute(ObjectName bean, String name)
+ throws MBeanException, AttributeNotFoundException,
+ InstanceNotFoundException, ReflectionException
+ {
+ if (bean == null || name == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("One of the supplied arguments was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ Object abean = getBean(bean);
+ checkSecurity(bean, name, "getAttribute");
+ if (abean instanceof DynamicMBean)
+ return ((DynamicMBean) abean).getAttribute(name);
+ else
+ try
+ {
+ return new StandardMBean(abean, null).getAttribute(name);
+ }
+ catch (NotCompliantMBeanException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to create dynamic bean.").initCause(e));
+ }
+ }
+
+
+ /**
+ * Returns the values of the named attributes from the specified
+ * management bean.
+ *
+ * @param bean the bean to retrieve the value from.
+ * @param names the names of the attributes to retrieve.
+ * @return the values of the attributes.
+ * @throws InstanceNotFoundException if the bean can not be found.
+ * @throws ReflectionException if an exception was thrown in trying
+ * to invoke the bean's accessor.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> bean or attribute
+ * name.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, bean,
+ * "getAttribute")</code>}. Additionally,
+ * for an attribute name, <code>n</code>, the
+ * caller's permission must imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, n, bean,
+ * "getAttribute")</code>} or that attribute will
+ * not be included.
+ *
+ * @see DynamicMBean#getAttributes(String[])
+ */
+ public AttributeList getAttributes(ObjectName bean, String[] names)
+ throws InstanceNotFoundException, ReflectionException
+ {
+ if (bean == null || names == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("One of the supplied arguments was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ Object abean = getBean(bean);
+ checkSecurity(bean, null, "getAttribute");
+ AttributeList list = new AttributeList(names.length);
+ for (int a = 0; a < names.length; ++a)
+ {
+ if (names[a] == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("Argument " + a + " was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ checkSecurity(bean, names[a], "getAttribute");
+ try
+ {
+ Object value;
+ if (abean instanceof DynamicMBean)
+ value = ((DynamicMBean) abean).getAttribute(names[a]);
+ else
+ try
+ {
+ value = new StandardMBean(abean, null).getAttribute(names[a]);
+ }
+ catch (NotCompliantMBeanException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to create dynamic bean.").initCause(e));
+ }
+ list.add(new Attribute(names[a], value));
+ }
+ catch (AttributeNotFoundException e)
+ {
+ /* Ignored */
+ }
+ catch (MBeanException e)
+ {
+ /* Ignored */
+ }
+ }
+ return list;
+ }
+
+
+ /**
+ * Returns the specified class loader. If the specified value is
+ * <code>null</code>, then the class loader of the server will be
+ * returned. If <code>l</code> is the requested class loader,
+ * and <code>r</code> is the actual class loader returned, then
+ * either <code>l</code> and <code>r</code> will be identical,
+ * or they will at least return the same class from
+ * {@link ClassLoader#loadClass(String)} for any given string.
+ * They may not be identical due to one or the other
+ * being wrapped in another class loader (e.g. for security).
+ *
+ * @param name the name of the class loader to return.
+ * @return the class loader.
+ * @throws InstanceNotFoundException if the class loader can not
+ * be found.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "getClassLoader")</code>
+ */
+ public ClassLoader getClassLoader(ObjectName name)
+ throws InstanceNotFoundException
+ {
+ if (name == null)
+ {
+ checkSecurity(null, null, "getClassLoader");
+ return getClass().getClassLoader();
+ }
+ Object bean = getBean(name);
+ checkSecurity(name, null, "getClassLoader");
+ return (ClassLoader) bean;
+ }
+
+ /**
+ * Returns the class loader of the specified management bean. If
+ * <code>l</code> is the requested class loader, and <code>r</code>
+ * is the actual class loader returned, then either <code>l</code>
+ * and <code>r</code> will be identical, or they will at least
+ * return the same class from {@link ClassLoader#loadClass(String)}
+ * for any given string. They may not be identical due to one or
+ * the other being wrapped in another class loader (e.g. for
+ * security).
+ *
+ * @param name the name of the bean whose class loader should be
+ * returned.
+ * @return the class loader.
+ * @throws InstanceNotFoundException if the bean is not registered
+ * with the server.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "getClassLoaderFor")</code>
+ */
+ public ClassLoader getClassLoaderFor(ObjectName name)
+ throws InstanceNotFoundException
+ {
+ Object bean = getBean(name);
+ checkSecurity(name, null, "getClassLoaderFor");
+ return bean.getClass().getClassLoader();
+ }
+
+ /**
+ * Returns the class loader repository used by this server.
+ *
+ * @return the class loader repository.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(null, null, null,
+ * "getClassLoaderRepository")</code>
+ */
+ public ClassLoaderRepository getClassLoaderRepository()
+ {
+ return repository;
+ }
+
+ /**
+ * Returns the default domain this server applies to beans that have
+ * no specified domain.
+ *
+ * @return the default domain.
+ */
+ public String getDefaultDomain()
+ {
+ return defaultDomain;
+ }
+
+ /**
+ * Returns an array containing all the domains used by beans registered
+ * with this server. The ordering of the array is undefined.
+ *
+ * @return the list of domains.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(null, null, name,
+ * "getDomains")</code>}. Additionally,
+ * for an domain, <code>d</code>, the
+ * caller's permission must imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(null, null,
+ * new ObjectName("d:x=x"), "getDomains")</code>}
+ * or that domain will not be included. Note
+ * that "x=x" is an arbitrary key-value pair
+ * provided to satisfy the constructor.
+ * @see ObjectName#getDomain()
+ */
+ public String[] getDomains()
+ {
+ checkSecurity(null, null, "getDomains");
+ Set<String> domains = new HashSet<String>();
+ Iterator<ObjectName> iterator = beans.keySet().iterator();
+ while (iterator.hasNext())
+ {
+ String d = iterator.next().getDomain();
+ try
+ {
+ checkSecurity(new ObjectName(d + ":x=x"), null, "getDomains");
+ domains.add(d);
+ }
+ catch (MalformedObjectNameException e)
+ {
+ /* Ignored */
+ }
+ }
+ return domains.toArray(new String[domains.size()]);
+ }
+
+ /**
+ * Returns the number of management beans registered with this server.
+ * This may be less than the real number if the caller's access is
+ * restricted.
+ *
+ * @return the number of registered beans.
+ */
+ public Integer getMBeanCount()
+ {
+ return Integer.valueOf(beans.size());
+ }
+
+ /**
+ * Returns information on the given management bean.
+ *
+ * @param name the name of the management bean.
+ * @return an instance of {@link MBeanInfo} for the bean.
+ * @throws IntrospectionException if an exception occurs in examining
+ * the bean.
+ * @throws InstanceNotFoundException if the bean can not be found.
+ * @throws ReflectionException if an exception occurs when trying
+ * to invoke {@link DynamicMBean#getMBeanInfo()}
+ * on the bean.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "getMBeanInfo")</code>}.
+ * @see DynamicMBean#getMBeanInfo()
+ */
+ public MBeanInfo getMBeanInfo(ObjectName name)
+ throws InstanceNotFoundException, IntrospectionException,
+ ReflectionException
+ {
+ Object bean = getBean(name);
+ checkSecurity(name, null, "getMBeanInfo");
+ try
+ {
+ Method method = bean.getClass().getMethod("getMBeanInfo");
+ return (MBeanInfo) method.invoke(bean);
+ }
+ catch (NoSuchMethodException e)
+ {
+ try
+ {
+ return new StandardMBean(bean, null).getMBeanInfo();
+ }
+ catch (NotCompliantMBeanException ex)
+ {
+ throw new IntrospectionException("An error occurred in executing " +
+ "getMBeanInfo on the bean: " + ex + ".");
+ }
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new ReflectionException(e, "Failed to call getMBeanInfo");
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new ReflectionException(e, "Failed to call getMBeanInfo");
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new ReflectionException(e, "The method threw an exception");
+ }
+ }
+
+ /**
+ * Returns the {@link ObjectInstance} created for the specified
+ * management bean on registration.
+ *
+ * @param name the name of the bean.
+ * @return the corresponding {@link ObjectInstance} instance.
+ * @throws InstanceNotFoundException if the bean can not be found.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "getObjectInstance")</code>
+ * @see #createMBean(String, ObjectName)
+ */
+ public ObjectInstance getObjectInstance(ObjectName name)
+ throws InstanceNotFoundException
+ {
+ ServerInfo bean = beans.get(name);
+ if (bean == null)
+ throw new InstanceNotFoundException("The bean, " + name +
+ ", was not found.");
+ return bean.getInstance();
+ }
+
+ /**
+ * <p>
+ * Creates an instance of the specified class using the list of
+ * class loaders from the {@link
+ * javax.management.loading.ClassLoaderRepository Class Loader
+ * Repository}. The class should have a public constructor
+ * with no arguments. A reference to the new instance is returned,
+ * but the instance is not yet registered with the server.
+ * </p>
+ * <p>
+ * This method is equivalent to calling {@link
+ * #instantiate(String, Object[], String[])
+ * <code>instantiate(name, (Object[]) null, (String[]) null)</code>}
+ * with <code>null</code> parameters and signature.
+ * </p>
+ *
+ * @param name the name of the class of bean to be instantiated.
+ * @return an instance of the given class.
+ * @throws ReflectionException if an exception is thrown during
+ * loading the class or calling the
+ * constructor.
+ * @throws MBeanException if the constructor throws an exception.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> name.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, null,
+ * "instantiate")</code>}.
+ * @see #instantiate(String, Object[], String[])
+ */
+ public Object instantiate(String name)
+ throws ReflectionException, MBeanException
+ {
+ return instantiate(name, (Object[]) null, (String[]) null);
+ }
+
+ /**
+ * Creates an instance of the specified class using the list of
+ * class loaders from the {@link
+ * javax.management.loading.ClassLoaderRepository Class Loader
+ * Repository}. The class should have a public constructor
+ * matching the supplied signature. A reference to the new
+ * instance is returned, but the instance is not yet
+ * registered with the server.
+ *
+ * @param name the name of the class of bean to be instantiated.
+ * @param params the parameters for the constructor.
+ * @param sig the signature of the constructor.
+ * @return an instance of the given class.
+ * @throws ReflectionException if an exception is thrown during
+ * loading the class or calling the
+ * constructor.
+ * @throws MBeanException if the constructor throws an exception.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> name.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, null,
+ * "instantiate")</code>}.
+ */
+ public Object instantiate(String name, Object[] params, String[] sig)
+ throws ReflectionException, MBeanException
+ {
+ checkSecurity(null, null, "instantiate");
+ if (name == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("The name was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ Class<?>[] sigTypes = new Class[sig.length];
+ for (int a = 0; a < sigTypes.length; ++a)
+ {
+ try
+ {
+ sigTypes[a] = repository.loadClass(sig[a]);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new ReflectionException(e, "The class, " + sigTypes[a] +
+ ", in the method signature " +
+ "could not be loaded.");
+ }
+ }
+ try
+ {
+ Constructor<?> cons =
+ repository.loadClass(name).getConstructor(sigTypes);
+ return cons.newInstance(params);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new ReflectionException(e, "The class, " + name +
+ ", of the constructor " +
+ "could not be loaded.");
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new ReflectionException(e, "The method, " + name +
+ ", could not be found.");
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new ReflectionException(e, "Failed to instantiate the object");
+ }
+ catch (InstantiationException e)
+ {
+ throw new ReflectionException(e, "Failed to instantiate the object");
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new MBeanException((Exception) e.getCause(), "The constructor "
+ + name + " threw an exception");
+ }
+ }
+
+ /**
+ * <p>
+ * Creates an instance of the specified class using the supplied
+ * class loader. If the class loader given is <code>null</code>,
+ * then the class loader of the server will be used. The class
+ * should have a public constructor with no arguments. A reference
+ * to the new instance is returned, but the instance is not yet
+ * registered with the server.
+ * </p>
+ * <p>
+ * This method is equivalent to calling {@link
+ * #instantiate(String, ObjectName, Object[], String[])
+ * <code>instantiate(name, loaderName, (Object[]) null,
+ * (String[]) null)</code>} with <code>null</code> parameters
+ * and signature.
+ * </p>
+ *
+ * @param name the name of the class of bean to be instantiated.
+ * @param loaderName the name of the class loader to use.
+ * @return an instance of the given class.
+ * @throws InstanceNotFoundException if the class loader is not
+ * registered with the server.
+ * @throws ReflectionException if an exception is thrown during
+ * loading the class or calling the
+ * constructor.
+ * @throws MBeanException if the constructor throws an exception.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> name.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, null,
+ * "instantiate")</code>}.
+ * @see #instantiate(String, Object[], String[])
+ */
+ public Object instantiate(String name, ObjectName loaderName)
+ throws InstanceNotFoundException, ReflectionException,
+ MBeanException
+ {
+ return instantiate(name, loaderName);
+ }
+
+ /**
+ * Creates an instance of the specified class using the supplied
+ * class loader. If the class loader given is <code>null</code>,
+ * then the class loader of the server will be used. The class
+ * should have a public constructor matching the supplied
+ * signature. A reference to the new instance is returned,
+ * but the instance is not yet registered with the server.
+ *
+ * @param name the name of the class of bean to be instantiated.
+ * @param loaderName the name of the class loader to use.
+ * @param params the parameters for the constructor.
+ * @param sig the signature of the constructor.
+ * @return an instance of the given class.
+ * @throws InstanceNotFoundException if the class loader is not
+ * registered with the server.
+ * @throws ReflectionException if an exception is thrown during
+ * loading the class or calling the
+ * constructor.
+ * @throws MBeanException if the constructor throws an exception.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> name.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, null,
+ * "instantiate")</code>}.
+ */
+ public Object instantiate(String name, ObjectName loaderName,
+ Object[] params, String[] sig)
+ throws InstanceNotFoundException, ReflectionException,
+ MBeanException
+ {
+ checkSecurity(null, null, "instantiate");
+ if (name == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("The name was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ ClassLoader loader = getClassLoader(loaderName);
+ Class<?>[] sigTypes = new Class[sig.length];
+ for (int a = 0; a < sig.length; ++a)
+ {
+ try
+ {
+ sigTypes[a] = Class.forName(sig[a], true, loader);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new ReflectionException(e, "The class, " + sig[a] +
+ ", in the method signature " +
+ "could not be loaded.");
+ }
+ }
+ try
+ {
+ Constructor<?> cons =
+ Class.forName(name, true, loader).getConstructor(sigTypes);
+ return cons.newInstance(params);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw new ReflectionException(e, "The class, " + name +
+ ", of the constructor " +
+ "could not be loaded.");
+ }
+ catch (NoSuchMethodException e)
+ {
+ throw new ReflectionException(e, "The method, " + name +
+ ", could not be found.");
+ }
+ catch (IllegalAccessException e)
+ {
+ throw new ReflectionException(e, "Failed to instantiate the object");
+ }
+ catch (InstantiationException e)
+ {
+ throw new ReflectionException(e, "Failed to instantiate the object");
+ }
+ catch (InvocationTargetException e)
+ {
+ throw new MBeanException((Exception) e.getCause(), "The constructor "
+ + name + " threw an exception");
+ }
+ }
+
+ /**
+ * Invokes the supplied operation on the specified management
+ * bean. The class objects specified in the signature are loaded
+ * using the same class loader as was used for the management bean.
+ *
+ * @param bean the management bean whose operation should be invoked.
+ * @param name the name of the operation to invoke.
+ * @param params the parameters of the operation.
+ * @param sig the signature of the operation.
+ * @return the return value of the method.
+ * @throws InstanceNotFoundException if the bean can not be found.
+ * @throws MBeanException if the method invoked throws an exception.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> name.
+ * @throws ReflectionException if an exception is thrown in invoking the
+ * method.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, name, bean,
+ * "invoke")</code>}.
+ * @see DynamicMBean#invoke(String, Object[], String[])
+ */
+ public Object invoke(ObjectName bean, String name, Object[] params, String[] sig)
+ throws InstanceNotFoundException, MBeanException,
+ ReflectionException
+ {
+ if (bean == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("The bean was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ Object abean = getBean(bean);
+ checkSecurity(bean, name, "invoke");
+ if (abean instanceof DynamicMBean)
+ return ((DynamicMBean) abean).invoke(name, params, sig);
+ else
+ try
+ {
+ return new StandardMBean(abean, null).invoke(name, params, sig);
+ }
+ catch (NotCompliantMBeanException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to create dynamic bean.").initCause(e));
+ }
+ }
+
+ /**
+ * <p>
+ * Returns true if the specified management bean is an instance
+ * of the supplied class.
+ * </p>
+ * <p>
+ * A bean, B, is an instance of a class, C, if either of the following
+ * conditions holds:
+ * </p>
+ * <ul>
+ * <li>The class name in B's {@link MBeanInfo} is equal to the supplied
+ * name.</li>
+ * <li>Both the class of B and C were loaded by the same class loader,
+ * and B is assignable to C.</li>
+ * </ul>
+ *
+ * @param name the name of the management bean.
+ * @param className the name of the class to test if <code>name</code> is
+ * an instance of.
+ * @return true if either B is directly an instance of the named class,
+ * or B is assignable to the class, given that both it and B's
+ * current class were loaded using the same class loader.
+ * @throws InstanceNotFoundException if the bean can not be found.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "isInstanceOf")</code>
+ */
+ public boolean isInstanceOf(ObjectName name, String className)
+ throws InstanceNotFoundException
+ {
+ Object bean = getBean(name);
+ checkSecurity(name, null, "isInstanceOf");
+ MBeanInfo info;
+ if (bean instanceof DynamicMBean)
+ info = ((DynamicMBean) bean).getMBeanInfo();
+ else
+ try
+ {
+ info = new StandardMBean(bean, null).getMBeanInfo();
+ }
+ catch (NotCompliantMBeanException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to create dynamic bean.").initCause(e));
+ }
+ if (info.getClassName().equals(className))
+ return true;
+ Class<?> bclass = bean.getClass();
+ try
+ {
+ Class<?> oclass = Class.forName(className);
+ return (bclass.getClassLoader().equals(oclass.getClassLoader()) &&
+ oclass.isAssignableFrom(bclass));
+ }
+ catch (ClassNotFoundException e)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Returns true if the specified management bean is registered with
+ * the server.
+ *
+ * @param name the name of the management bean.
+ * @return true if the bean is registered.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> bean name.
+ */
+ public boolean isRegistered(ObjectName name)
+ {
+ if (name == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("The name was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ return beans.containsKey(name);
+ }
+
+ /**
+ * <p>
+ * Returns a set of {@link ObjectInstance}s matching the specified
+ * criteria. The full set of beans registered with the server
+ * are passed through two filters:
+ * </p>
+ * <ol>
+ * <li>Pattern matching is performed using the supplied
+ * {@link ObjectName}.</li>
+ * <li>The supplied query expression is applied.</li>
+ * </ol>
+ * <p>
+ * If both the object name and the query expression are <code>null</code>,
+ * or the object name has no domain and no key properties,
+ * no filtering will be performed and all beans are returned.
+ * </p>
+ *
+ * @param name an {@link ObjectName} to use as a filter.
+ * @param query a query expression to apply to each of the beans that match
+ * the given object name.
+ * @return a set of {@link ObjectInstance}s matching the filtered beans.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(null, null, name,
+ * "queryMBeans")</code>}. Additionally,
+ * for an bean, <code>b</code>, the
+ * caller's permission must imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, b, name,
+ * "queryMBeans")</code>} or that bean will
+ * not be included. Such an exception may also
+ * arise from the execution of the query, in which
+ * case that particular bean will again be excluded.
+ */
+ public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query)
+ {
+ checkSecurity(name, null, "queryMBeans");
+ Set<ObjectInstance> results = new HashSet<ObjectInstance>();
+ for (Map.Entry<ObjectName,ServerInfo> entry : beans.entrySet())
+ {
+ ObjectName nextName = entry.getKey();
+ checkSecurity(name, nextName.toString(), "queryMBeans");
+ try
+ {
+ if ((name == null || name.apply(nextName)) &&
+ (query == null || query.apply(nextName)))
+ results.add(entry.getValue().getInstance());
+ }
+ catch (BadStringOperationException e)
+ {
+ /* Ignored -- assume false result */
+ }
+ catch (BadBinaryOpValueExpException e)
+ {
+ /* Ignored -- assume false result */
+ }
+ catch (BadAttributeValueExpException e)
+ {
+ /* Ignored -- assume false result */
+ }
+ catch (InvalidApplicationException e)
+ {
+ /* Ignored -- assume false result */
+ }
+ }
+ return results;
+ }
+
+ /**
+ * <p>
+ * Returns a set of {@link ObjectName}s matching the specified
+ * criteria. The full set of beans registered with the server
+ * are passed through two filters:
+ * </p>
+ * <ol>
+ * <li>Pattern matching is performed using the supplied
+ * {@link ObjectName}.</li>
+ * <li>The supplied query expression is applied.</li>
+ * </ol>
+ * <p>
+ * If both the object name and the query expression are <code>null</code>,
+ * or the object name has no domain and no key properties,
+ * no filtering will be performed and all beans are returned.
+ * </p>
+ *
+ * @param name an {@link ObjectName} to use as a filter.
+ * @param query a query expression to apply to each of the beans that match
+ * the given object name.
+ * @return a set of {@link ObjectName}s matching the filtered beans.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(null, null, name,
+ * "queryNames")</code>}. Additionally,
+ * for an name, <code>n</code>, the
+ * caller's permission must imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, n, name,
+ * "queryNames")</code>} or that name will
+ * not be included. Such an exception may also
+ * arise from the execution of the query, in which
+ * case that particular bean will again be excluded.
+ * Note that these permissions are implied if the
+ * <code>queryMBeans</code> permissions are available.
+ */
+ public Set<ObjectName> queryNames(ObjectName name, QueryExp query)
+ {
+ checkSecurity(name, null, "queryNames");
+ Set<ObjectName> results = new HashSet<ObjectName>();
+ for (ObjectName nextName : beans.keySet())
+ {
+ checkSecurity(name, nextName.toString(), "queryNames");
+ try
+ {
+ if ((name == null || name.apply(nextName)) &&
+ (query == null || query.apply(nextName)))
+ results.add(nextName);
+ }
+ catch (BadStringOperationException e)
+ {
+ /* Ignored -- assume false result */
+ }
+ catch (BadBinaryOpValueExpException e)
+ {
+ /* Ignored -- assume false result */
+ }
+ catch (BadAttributeValueExpException e)
+ {
+ /* Ignored -- assume false result */
+ }
+ catch (InvalidApplicationException e)
+ {
+ /* Ignored -- assume false result */
+ }
+ }
+ return results;
+ }
+
+ /**
+ * Registers the supplied instance with the server, using the specified
+ * {@link ObjectName}. If the name given is <code>null</code>, then
+ * the bean supplied is expected to implement the {@link MBeanRegistration}
+ * interface and provide the name via the
+ * {@link MBeanRegistration#preRegister preRegister} method
+ * of this interface.
+ *
+ * @param obj the object to register with the server.
+ * @param name the name under which to register the object,
+ * or <code>null</code> if the {@link MBeanRegistration}
+ * interface should be used.
+ * @return an {@link ObjectInstance} containing the supplied
+ * {@link ObjectName} along with the name of the bean's class.
+ * @throws InstanceAlreadyExistsException if a matching instance
+ * already exists.
+ * @throws MBeanRegistrationException if an exception occurs in
+ * calling the preRegister
+ * method.
+ * @throws NotCompliantMBeanException if the created bean is not
+ * compliant with the JMX specification.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> object.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "registerMBean")</code>}. <code>className</code>
+ * here corresponds to the result of
+ * {@link MBeanInfo#getClassName()} for objects of
+ * this class. If this check succeeds, a check
+ * is also made on its
+ * {@link java.security.ProtectionDomain} to ensure
+ * it implies {@link MBeanTrustPermission(String)
+ * <code>MBeanTrustPermission("register")</code>}.
+ * The use of the {@link MBeanRegistration} interface
+ * results in another {@link MBeanPermission} check
+ * being made on the returned {@link ObjectName}.
+ */
+ public ObjectInstance registerMBean(Object obj, ObjectName name)
+ throws InstanceAlreadyExistsException, MBeanRegistrationException,
+ NotCompliantMBeanException
+ {
+ SecurityManager sm = System.getSecurityManager();
+ Class<?> cl = obj.getClass();
+ String className = cl.getName();
+ if (sm != null)
+ {
+ sm.checkPermission(new MBeanPermission(className, null, name,
+ "registerMBean"));
+ if (!(cl.getProtectionDomain().implies(new MBeanTrustPermission("register"))))
+ throw new SecurityException("The protection domain of the object's class" +
+ "does not imply the trust permission," +
+ "register");
+ }
+ if (obj == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("The object was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ MBeanRegistration register = null;
+ if (obj instanceof MBeanRegistration)
+ register = (MBeanRegistration) obj;
+ if (name == null && register == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("The name was null and " +
+ "the bean does not implement " +
+ "MBeanRegistration.");
+ throw new RuntimeOperationsException(e);
+ }
+ if (register != null)
+ {
+ try
+ {
+ name = register.preRegister(this, name);
+ if (name == null)
+ {
+ RuntimeException e =
+ new NullPointerException("The name returned by " +
+ "MBeanRegistration.preRegister() " +
+ "was null");
+ throw e;
+ }
+ if (sm != null)
+ sm.checkPermission(new MBeanPermission(className, null, name,
+ "registerMBean"));
+ }
+ catch (SecurityException e)
+ {
+ register.postRegister(Boolean.FALSE);
+ throw e;
+ }
+ catch (Exception e)
+ {
+ register.postRegister(Boolean.FALSE);
+ throw new MBeanRegistrationException(e, "Pre-registration failed.");
+ }
+ }
+ ObjectInstance obji = new ObjectInstance(name, className);
+ if (beans.putIfAbsent(name, new ServerInfo(obji, obj)) != null)
+ {
+ if (register != null)
+ register.postRegister(Boolean.FALSE);
+ throw new InstanceAlreadyExistsException(name + "is already registered.");
+ }
+ if (register != null)
+ register.postRegister(Boolean.TRUE);
+ notify(name, MBeanServerNotification.REGISTRATION_NOTIFICATION);
+ return obji;
+ }
+
+ /**
+ * Removes the specified listener from the list of recipients
+ * of notifications from the supplied bean. This includes all
+ * combinations of filters and passback objects registered for
+ * this listener. For more specific removal of listeners, see
+ * {@link #removeNotificationListener(ObjectName,
+ * NotificationListener,NotificationFilter,Object)}
+ *
+ * @param name the name of the management bean from which the
+ * listener should be removed.
+ * @param listener the listener to remove.
+ * @throws InstanceNotFoundException if the bean can not be found.
+ * @throws ListenerNotFoundException if the specified listener
+ * is not registered with the bean.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "removeNotificationListener")</code>}.
+ * @see #addNotificationListener(NotificationListener, NotificationFilter,
+ * java.lang.Object)
+ * @see NotificationBroadcaster#removeNotificationListener(NotificationListener)
+ */
+ public void removeNotificationListener(ObjectName name,
+ NotificationListener listener)
+ throws InstanceNotFoundException, ListenerNotFoundException
+ {
+ Object bean = getBean(name);
+ checkSecurity(name, null, "removeNotificationListener");
+ if (bean instanceof NotificationBroadcaster)
+ {
+ NotificationBroadcaster bbean = (NotificationBroadcaster) bean;
+ bbean.removeNotificationListener(listener);
+ LazyListenersHolder.listeners.remove(listener);
+ }
+ }
+
+ /**
+ * Removes the specified listener from the list of recipients
+ * of notifications from the supplied bean. Only the first instance with
+ * the supplied filter and passback object is removed.
+ * <code>null</code> is used as a valid value for these parameters,
+ * rather than as a way to remove all registration instances for
+ * the specified listener; for this behaviour instead, see
+ * {@link #removeNotificationListener(ObjectName, NotificationListener)}.
+ *
+ * @param name the name of the management bean from which the
+ * listener should be removed.
+ * @param listener the listener to remove.
+ * @param filter the filter of the listener to remove.
+ * @param passback the passback object of the listener to remove.
+ * @throws InstanceNotFoundException if the bean can not be found.
+ * @throws ListenerNotFoundException if the specified listener
+ * is not registered with the bean.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "removeNotificationListener")</code>}.
+ * @see #addNotificationListener(ObjectName, NotificationListener,
+ * NotificationFilter, Object)
+ * @see NotificationEmitter#removeNotificationListener(NotificationListener,
+ * NotificationFilter,
+ * Object)
+ */
+ public void removeNotificationListener(ObjectName name,
+ NotificationListener listener,
+ NotificationFilter filter,
+ Object passback)
+ throws InstanceNotFoundException, ListenerNotFoundException
+ {
+ Object bean = getBean(name);
+ checkSecurity(name, null, "removeNotificationListener");
+ if (bean instanceof NotificationEmitter)
+ {
+ NotificationEmitter bbean = (NotificationEmitter) bean;
+ bbean.removeNotificationListener(listener, filter, passback);
+ LazyListenersHolder.listeners.remove(listener);
+ }
+ }
+
+ /**
+ * Removes the specified listener from the list of recipients
+ * of notifications from the supplied bean. This includes all
+ * combinations of filters and passback objects registered for
+ * this listener. For more specific removal of listeners, see
+ * {@link #removeNotificationListener(ObjectName,
+ * ObjectName,NotificationFilter,Object)}
+ *
+ * @param name the name of the management bean from which the
+ * listener should be removed.
+ * @param listener the name of the listener to remove.
+ * @throws InstanceNotFoundException if a name doesn't match a registered
+ * bean.
+ * @throws ListenerNotFoundException if the specified listener
+ * is not registered with the bean.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "removeNotificationListener")</code>}.
+ * @see #addNotificationListener(NotificationListener, NotificationFilter,
+ * java.lang.Object)
+ * @see NotificationBroadcaster#removeNotificationListener(NotificationListener)
+ */
+ public void removeNotificationListener(ObjectName name, ObjectName listener)
+ throws InstanceNotFoundException, ListenerNotFoundException
+ {
+ Object lbean = getBean(listener);
+ if (!(lbean instanceof NotificationListener))
+ {
+ RuntimeException e =
+ new IllegalArgumentException("The supplied listener name does not " +
+ "correspond to a notification listener.");
+ throw new RuntimeOperationsException(e);
+ }
+ removeNotificationListener(name, ((NotificationListener) lbean));
+ }
+
+ /**
+ * Removes the specified listener from the list of recipients
+ * of notifications from the supplied bean. Only the first instance with
+ * the supplied filter and passback object is removed.
+ * <code>null</code> is used as a valid value for these parameters,
+ * rather than as a way to remove all registration instances for
+ * the specified listener; for this behaviour instead, see
+ * {@link #removeNotificationListener(ObjectName, ObjectName)}.
+ *
+ * @param name the name of the management bean from which the
+ * listener should be removed.
+ * @param listener the name of the listener to remove.
+ * @param filter the filter of the listener to remove.
+ * @param passback the passback object of the listener to remove.
+ * @throws InstanceNotFoundException if a name doesn't match a registered
+ * bean.
+ * @throws ListenerNotFoundException if the specified listener
+ * is not registered with the bean.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "removeNotificationListener")</code>}.
+ * @see #addNotificationListener(ObjectName, NotificationListener,
+ * NotificationFilter, Object)
+ * @see NotificationEmitter#removeNotificationListener(NotificationListener,
+ * NotificationFilter,
+ * Object)
+ */
+ public void removeNotificationListener(ObjectName name,
+ ObjectName listener,
+ NotificationFilter filter,
+ Object passback)
+ throws InstanceNotFoundException, ListenerNotFoundException
+ {
+ Object lbean = getBean(listener);
+ if (!(lbean instanceof NotificationListener))
+ {
+ RuntimeException e =
+ new IllegalArgumentException("The supplied listener name does not " +
+ "correspond to a notification listener.");
+ throw new RuntimeOperationsException(e);
+ }
+ removeNotificationListener(name, ((NotificationListener) lbean), filter,
+ passback);
+ }
+
+ /**
+ * Sets the value of the specified attribute of the supplied
+ * management bean.
+ *
+ * @param name the name of the management bean.
+ * @param attribute the attribute to set.
+ * @throws InstanceNotFoundException if the bean can not be found.
+ * @throws AttributeNotFoundException if the attribute does not
+ * correspond to an attribute
+ * of the bean.
+ * @throws InvalidAttributeValueException if the value is invalid
+ * for this particular
+ * attribute of the bean.
+ * @throws MBeanException if setting the attribute causes
+ * the bean to throw an exception (which
+ * becomes the cause of this exception).
+ * @throws ReflectionException if an exception occurred in trying
+ * to use the reflection interface
+ * to lookup the attribute. The
+ * thrown exception is the cause of
+ * this exception.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> bean or attribute
+ * name.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, name, bean,
+ * "setAttribute")</code>}.
+ * @see #getAttribute(ObjectName, String)
+ * @see DynamicMBean#setAttribute(Attribute)
+ */
+ public void setAttribute(ObjectName name, Attribute attribute)
+ throws InstanceNotFoundException, AttributeNotFoundException,
+ InvalidAttributeValueException, MBeanException,
+ ReflectionException
+ {
+ if (attribute == null || name == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("One of the supplied arguments was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ Object bean = getBean(name);
+ checkSecurity(name, attribute.getName(), "setAttribute");
+ if (bean instanceof DynamicMBean)
+ ((DynamicMBean) bean).setAttribute(attribute);
+ else
+ try
+ {
+ new StandardMBean(bean, null).setAttribute(attribute);
+ }
+ catch (NotCompliantMBeanException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to create dynamic bean.").initCause(e));
+ }
+ }
+
+ /**
+ * Sets the value of each of the specified attributes
+ * of the supplied management bean to that specified by
+ * the {@link Attribute} object. The returned list contains
+ * the attributes that were set and their new values.
+ *
+ * @param name the name of the management bean.
+ * @param attributes the attributes to set.
+ * @return a list of the changed attributes.
+ * @throws InstanceNotFoundException if the bean can not be found.
+ * @throws ReflectionException if an exception occurred in trying
+ * to use the reflection interface
+ * to lookup the attribute. The
+ * thrown exception is the cause of
+ * this exception.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> bean or attribute
+ * list.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, bean,
+ * "setAttribute")</code>}. Additionally,
+ * for an attribute name, <code>n</code>, the
+ * caller's permission must imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, n, bean,
+ * "setAttribute")</code>} or that attribute will
+ * not be included.
+ * @see #getAttributes(ObjectName, String[])
+ * @see DynamicMBean#setAttributes(AttributeList)
+ */
+ public AttributeList setAttributes(ObjectName name, AttributeList attributes)
+ throws InstanceNotFoundException, ReflectionException
+ {
+ if (name == null || attributes == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("One of the supplied arguments was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ Object abean = getBean(name);
+ checkSecurity(name, null, "setAttribute");
+ AttributeList list = new AttributeList(attributes.size());
+ Iterator<Object> it = attributes.iterator();
+ while (it.hasNext())
+ {
+ try
+ {
+ Attribute attrib = (Attribute) it.next();
+ if (attrib == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("An attribute was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ checkSecurity(name, attrib.getName(), "setAttribute");
+ if (abean instanceof DynamicMBean)
+ ((DynamicMBean) abean).setAttribute(attrib);
+ else
+ try
+ {
+ new StandardMBean(abean, null).setAttribute(attrib);
+ }
+ catch (NotCompliantMBeanException e)
+ {
+ throw (Error)
+ (new InternalError("Failed to create dynamic bean.").initCause(e));
+ }
+ list.add(attrib);
+ }
+ catch (AttributeNotFoundException e)
+ {
+ /* Ignored */
+ }
+ catch (InvalidAttributeValueException e)
+ {
+ /* Ignored */
+ }
+ catch (MBeanException e)
+ {
+ /* Ignored */
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Unregisters the specified management bean. Following this operation,
+ * the bean instance is no longer accessible from the server via this
+ * name. Prior to unregistering the bean, the
+ * {@link MBeanRegistration#preDeregister()} method will be called if
+ * the bean implements the {@link MBeanRegistration} interface.
+ *
+ * @param name the name of the management bean.
+ * @throws InstanceNotFoundException if the bean can not be found.
+ * @throws MBeanRegistrationException if an exception occurs in
+ * calling the preDeregister
+ * method.
+ * @throws RuntimeOperationsException if an {@link IllegalArgumentException}
+ * is thrown by the server due to a
+ * <code>null</code> bean name or a
+ * request being made to unregister the
+ * {@link MBeanServerDelegate} bean.
+ * @throws SecurityException if a security manager exists and the
+ * caller's permissions don't imply {@link
+ * MBeanPermission(String,String,ObjectName,String)
+ * <code>MBeanPermission(className, null, name,
+ * "unregisterMBean")</code>}.
+ */
+ public void unregisterMBean(ObjectName name)
+ throws InstanceNotFoundException, MBeanRegistrationException
+ {
+ if (name == null)
+ {
+ RuntimeException e =
+ new IllegalArgumentException("The name was null.");
+ throw new RuntimeOperationsException(e);
+ }
+ if (name.equals(DELEGATE_NAME))
+ {
+ RuntimeException e =
+ new IllegalArgumentException("The delegate can not be unregistered.");
+ throw new RuntimeOperationsException(e);
+ }
+ Object bean = getBean(name);
+ checkSecurity(name, null, "unregisterMBean");
+ MBeanRegistration register = null;
+ if (bean instanceof MBeanRegistration)
+ {
+ register = (MBeanRegistration) bean;
+ try
+ {
+ register.preDeregister();
+ }
+ catch (Exception e)
+ {
+ throw new MBeanRegistrationException(e, "Pre-deregistration failed.");
+ }
+ }
+ beans.remove(name);
+ notify(name, MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
+ if (register != null)
+ register.postDeregister();
+ }
+
+ /**
+ * Notifies the delegate of beans being registered
+ * and unregistered.
+ *
+ * @param name the bean being registered.
+ * @param type the type of notification;
+ * {@code REGISTRATION_NOTIFICATION} or
+ * {@code UNREGISTRATION_NOTIFICATION}.
+ */
+ private void notify(ObjectName name, String type)
+ {
+ delegate.sendNotification
+ (new MBeanServerNotification
+ (type, DELEGATE_NAME, sequenceNumber.getAndIncrement(), name));
+ }
+
+ /**
+ * Input stream which deserializes using the given classloader.
+ */
+ private class ServerInputStream
+ extends ObjectInputStream
+ {
+
+ private ClassLoader cl;
+
+ public ServerInputStream(InputStream is, ClassLoader cl)
+ throws IOException, StreamCorruptedException
+ {
+ super(is);
+ this.cl = cl;
+ }
+
+ protected Class<?> resolveClass(ObjectStreamClass osc)
+ throws ClassNotFoundException, IOException
+ {
+ try
+ {
+ return Class.forName(osc.getName(), true, cl);
+ }
+ catch (ClassNotFoundException e)
+ {
+ return super.resolveClass(osc);
+ }
+ }
+
+ }
+
+ /**
+ * Holder for information on registered beans.
+ */
+ private class ServerInfo
+ {
+ private ObjectInstance instance;
+
+ private Object object;
+
+ public ServerInfo(ObjectInstance instance, Object object)
+ {
+ this.instance = instance;
+ this.object = object;
+ }
+
+ public Object getObject()
+ {
+ return object;
+ }
+
+ public ObjectInstance getInstance()
+ {
+ return instance;
+ }
+ }
+
+ /**
+ * Notification listener which removes direct references
+ * to beans.
+ */
+ private class ServerNotificationListener
+ implements NotificationListener
+ {
+
+ /**
+ * The bean from which notifications are emitted.
+ */
+ Object bean;
+
+ /**
+ * The {@link ObjectName} of the emitting bean.
+ */
+ ObjectName name;
+
+ /**
+ * The real {@link NotificationListener}.
+ */
+ NotificationListener listener;
+
+ /**
+ * Constructs a new {@link ServerNotificationListener} replacing
+ * occurrences of <code>bean</code> with its name.
+ *
+ * @param bean the bean emitting notifications.
+ * @param name the object name of the emitting bean.
+ * @param listener the listener events eventually reach.
+ */
+ public ServerNotificationListener(Object bean, ObjectName name,
+ NotificationListener listener)
+ {
+ this.bean = bean;
+ this.name = name;
+ this.listener = listener;
+ }
+
+ /**
+ * Replace a direct reference to <code>bean</code> with its
+ * object reference, if necessary, before calling the listener.
+ *
+ * @param notif the notification being emitted.
+ * @param handback an object that will be returned to the notification
+ * listener when an event occurs.
+ */
+ public void handleNotification(Notification notif, Object handback)
+ {
+ if (notif.getSource() == bean)
+ notif.setSource(name);
+ listener.handleNotification(notif, handback);
+ }
+
+ }
+
+}
diff --git a/libjava/classpath/gnu/javax/management/Translator.java b/libjava/classpath/gnu/javax/management/Translator.java
new file mode 100644
index 000000000..38d575aca
--- /dev/null
+++ b/libjava/classpath/gnu/javax/management/Translator.java
@@ -0,0 +1,550 @@
+/* Translator.java -- Performs MXBean data type translation.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+package gnu.javax.management;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+
+import javax.management.JMX;
+import javax.management.MBeanServerInvocationHandler;
+
+import javax.management.openmbean.ArrayType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenMBeanParameterInfo;
+import javax.management.openmbean.OpenMBeanParameterInfoSupport;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+/**
+ * Translates Java data types to their equivalent
+ * open data type, and vice versa, according to the
+ * {@link javax.management.MXBean} rules.
+ *
+ * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
+ */
+public final class Translator
+{
+
+ /**
+ * Translates the input Java data types to the equivalent
+ * open data types.
+ *
+ * @param jtypes the Java types supplied as parameters.
+ * @param method the method that was called.
+ * @return the equivalent open types required by the {@link MXBean}.
+ * @throws Throwable if an exception is thrown in performing the
+ * conversion.
+ */
+ public static final Object[] fromJava(Object[] jtypes, Method method)
+ throws Throwable
+ {
+ Type[] gtypes = method.getGenericParameterTypes();
+ Object[] otypes = new Object[jtypes.length];
+ for (int a = 0; a < jtypes.length; ++a)
+ otypes[a] = fromJava(jtypes[a], gtypes[a]);
+ return otypes;
+ }
+
+ /**
+ * Translates the input Java data type to the equivalent
+ * open data type.
+ *
+ * @param jtype the Java type supplied as a parameter.
+ * @param type the type of the parameter.
+ * @return the equivalent open type required by the {@link MXBean}.
+ * @throws Throwable if an exception is thrown in performing the
+ * conversion.
+ */
+ public static final Object fromJava(Object jtype, Type type)
+ throws Throwable
+ {
+ if (jtype == null)
+ return null;
+ Class<?> jclass = jtype.getClass();
+ if (OpenType.ALLOWED_CLASSNAMES_LIST.contains(jclass.getName()))
+ return jtype;
+ if (jclass.isArray())
+ {
+ Class<?> ctype = jclass.getComponentType();
+ if (ctype.isPrimitive())
+ return jtype;
+ if (OpenType.ALLOWED_CLASSNAMES_LIST.contains(ctype.getName()))
+ return jtype;
+ Object[] elems = (Object[]) jtype;
+ Object[] celems = new Object[elems.length];
+ for (int a = 0; a < elems.length; ++a)
+ celems[a] = fromJava(elems[a], elems[a].getClass());
+ return makeArraySpecific(celems);
+ }
+ String tName = getTypeName(type);
+ if (jtype instanceof List || jtype instanceof Set ||
+ jtype instanceof SortedSet)
+ {
+ if (jtype instanceof SortedSet)
+ {
+ ParameterizedType ptype = (ParameterizedType) type;
+ Class<?> elemClass = (Class<?>) ptype.getActualTypeArguments()[0];
+ if (!Comparable.class.isAssignableFrom(elemClass))
+ throw new IllegalArgumentException(jtype + " has a " +
+ "non-comparable element " +
+ "type, " + elemClass);
+ if (((SortedSet<?>) jtype).comparator() != null)
+ throw new IllegalArgumentException(jtype + " does not " +
+ "use natural ordering.");
+ }
+ Collection<?> elems = (Collection<?>) jtype;
+ int numElems = elems.size();
+ Object[] celems = new Object[numElems];
+ Iterator<?> i = elems.iterator();
+ for (int a = 0; a < numElems; ++a)
+ {
+ Object elem = i.next();
+ celems[a] = fromJava(elem, elem.getClass());
+ }
+ return makeArraySpecific(celems);
+ }
+ if (jtype instanceof Enum)
+ return ((Enum<?>) jtype).name();
+ if (jtype instanceof Map || jtype instanceof SortedMap)
+ {
+ int lparam = tName.indexOf("<");
+ int comma = tName.indexOf(",", lparam);
+ int rparam = tName.indexOf(">", comma);
+ String key = tName.substring(lparam + 1, comma).trim();
+ String value = tName.substring(comma + 1, rparam).trim();
+ String typeName = null;
+ if (jtype instanceof Map)
+ typeName = "java.util.Map" + tName.substring(lparam);
+ else
+ {
+ Class<?> keyClass = Class.forName(key);
+ if (!Comparable.class.isAssignableFrom(keyClass))
+ throw new IllegalArgumentException(jtype + " has a " +
+ "non-comparable element " +
+ "type, " + keyClass);
+ if (((SortedMap<?,?>) jtype).comparator() != null)
+ throw new IllegalArgumentException(jtype + " does not " +
+ "use natural ordering.");
+ typeName = "java.util.SortedMap" + tName.substring(lparam);
+ }
+ OpenType<?> k = translate(key).getOpenType();
+ OpenType<?> v = translate(value).getOpenType();
+ CompositeType rowType = new CompositeType(typeName, typeName,
+ new String[] { "key", "value" },
+ new String[] { "Map key", "Map value"},
+ new OpenType[] {k,v});
+ TabularType tabType = new TabularType(typeName, typeName, rowType,
+ new String[]{"key"});
+ TabularData data = new TabularDataSupport(tabType);
+ for (Map.Entry<?,?> entry : ((Map<?,?>) jtype).entrySet())
+ {
+ try
+ {
+ data.put(new CompositeDataSupport(rowType,
+ new String[] {
+ "key",
+ "value"
+ },
+ new Object[] {
+ entry.getKey(),
+ entry.getValue()
+ }));
+ }
+ catch (OpenDataException e)
+ {
+ throw (InternalError) (new InternalError("A problem occurred " +
+ "converting the map " +
+ "to a composite data " +
+ "structure.").initCause(e));
+ }
+ }
+ return data;
+ }
+ if (JMX.isMXBeanInterface(jclass))
+ {
+ try
+ {
+ MBeanServerInvocationHandler ih = (MBeanServerInvocationHandler)
+ Proxy.getInvocationHandler(jtype);
+ return ih.getObjectName();
+ }
+ catch (IllegalArgumentException e)
+ {
+ throw new IllegalArgumentException("For a MXBean to be translated " +
+ "to an open type, it must be a " +
+ "proxy.", e);
+ }
+ catch (ClassCastException e)
+ {
+ throw new IllegalArgumentException("For a MXBean to be translated " +
+ "to an open type, it must have a " +
+ "MBeanServerInvocationHandler.", e);
+ }
+ }
+ /* FIXME: Handle other types */
+ throw new IllegalArgumentException("The type, " + jtype +
+ ", is not convertible.");
+ }
+
+ /**
+ * Translates the returned open data type to the value
+ * required by the interface.
+ *
+ * @param otype the open type returned by the method call.
+ * @param method the method that was called.
+ * @return the equivalent return type required by the interface.
+ * @throws Throwable if an exception is thrown in performing the
+ * conversion.
+ */
+ public static final Object toJava(Object otype, Method method)
+ throws Throwable
+ {
+ Class<?> returnType = method.getReturnType();
+ if (returnType.isEnum())
+ {
+ String ename = (String) otype;
+ Enum<?>[] constants = (Enum[]) returnType.getEnumConstants();
+ for (Enum<?> c : constants)
+ if (c.name().equals(ename))
+ return c;
+ }
+ if (List.class.isAssignableFrom(returnType))
+ {
+ Object[] elems = (Object[]) otype;
+ List<Object> l = new ArrayList<Object>(elems.length);
+ for (Object elem : elems)
+ l.add(elem);
+ return l;
+ }
+ if (Map.class.isAssignableFrom(returnType))
+ {
+ TabularData data = (TabularData) otype;
+ Map<Object,Object> m = new HashMap<Object,Object>(data.size());
+ for (Object val : data.values())
+ {
+ CompositeData vals = (CompositeData) val;
+ m.put(vals.get("key"), vals.get("value"));
+ }
+ return m;
+ }
+ try
+ {
+ Method m = returnType.getMethod("from",
+ new Class[]
+ { CompositeData.class });
+ return m.invoke(null, (CompositeData) otype);
+ }
+ catch (NoSuchMethodException e)
+ {
+ /* Ignored; we expect this if this
+ isn't a from(CompositeData) class */
+ }
+ return otype;
+ }
+
+ /**
+ * Creates a new array which has the specific type
+ * used by the elements of the original {@link Object}
+ * array supplied.
+ *
+ * @param arr a series of elements in an {@link Object}
+ * array.
+ * @return the same elements in a new array of the specific
+ * type.
+ */
+ private static final Object[] makeArraySpecific(Object[] arr)
+ {
+ Object[] rcelems = (Object[]) Array.newInstance(arr[0].getClass(),
+ arr.length);
+ System.arraycopy(arr, 0, rcelems, 0, arr.length);
+ return rcelems;
+ }
+
+ /**
+ * Translates the name of a type into an equivalent
+ * {@link javax.management.openmbean.OpenMBeanParameterInfo}
+ * that describes it.
+ *
+ * @param type the type to describe.
+ * @return an instance of
+ * {@link javax.management.openmbean.OpenMBeanParameterInfo},
+ * describing the translated type and limits of the given type.
+ * @throws OpenDataException if a type is not open.
+ */
+ public static final OpenMBeanParameterInfo translate(String type)
+ throws OpenDataException
+ {
+ if (type.equals("boolean") || type.equals(Boolean.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.BOOLEAN,
+ null,
+ new Boolean[] {
+ Boolean.TRUE,
+ Boolean.FALSE
+ });
+ if (type.equals("byte") || type.equals(Byte.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.BYTE,
+ null,
+ Byte.valueOf(Byte.MIN_VALUE),
+ Byte.valueOf(Byte.MAX_VALUE));
+ if (type.equals("char") || type.equals(Character.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.CHARACTER,
+ null,
+ Character.valueOf(Character.MIN_VALUE),
+ Character.valueOf(Character.MAX_VALUE));
+ if (type.equals("double") || type.equals(Double.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.DOUBLE,
+ null,
+ Double.valueOf(Double.MIN_VALUE),
+ Double.valueOf(Double.MAX_VALUE));
+ if (type.equals("float") || type.equals(Float.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.FLOAT,
+ null,
+ Float.valueOf(Float.MIN_VALUE),
+ Float.valueOf(Float.MAX_VALUE));
+ if (type.equals("int") || type.equals(Integer.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.INTEGER,
+ null,
+ Integer.valueOf(Integer.MIN_VALUE),
+ Integer.valueOf(Integer.MAX_VALUE));
+ if (type.equals("long") || type.equals(Long.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.LONG,
+ null,
+ Long.valueOf(Long.MIN_VALUE),
+ Long.valueOf(Long.MAX_VALUE));
+ if (type.equals("short") || type.equals(Short.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.SHORT,
+ null,
+ Short.valueOf(Short.MIN_VALUE),
+ Short.valueOf(Short.MAX_VALUE));
+ if (type.equals(String.class.getName()))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.STRING);
+ if (type.equals("void"))
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.VOID);
+ if (type.startsWith("java.util.Map"))
+ {
+ int lparam = type.indexOf("<");
+ int comma = type.indexOf(",", lparam);
+ int rparam = type.indexOf(">", comma);
+ String key = type.substring(lparam + 1, comma).trim();
+ OpenType<?> k = translate(key).getOpenType();
+ OpenType<?> v = translate(type.substring(comma + 1, rparam).trim()).getOpenType();
+ CompositeType ctype = new CompositeType(Map.class.getName(), Map.class.getName(),
+ new String[] { "key", "value" },
+ new String[] { "Map key", "Map value"},
+ new OpenType[] { k, v});
+ TabularType ttype = new TabularType(key, key, ctype,
+ new String[] { "key" });
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ ttype);
+ }
+ if (type.startsWith("java.util.List"))
+ {
+ int lparam = type.indexOf("<");
+ int rparam = type.indexOf(">");
+ OpenType<?> e = translate(type.substring(lparam + 1, rparam).trim()).getOpenType();
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ new ArrayType<OpenType<?>>(1, e)
+ );
+ }
+ Class<?> c;
+ try
+ {
+ c = Class.forName(type);
+ }
+ catch (ClassNotFoundException e)
+ {
+ throw (InternalError)
+ (new InternalError("The class for a type used in a management bean " +
+ "could not be loaded.").initCause(e));
+ }
+ if (c.isEnum())
+ {
+ Object[] values = c.getEnumConstants();
+ String[] names = new String[values.length];
+ for (int a = 0; a < values.length; ++a)
+ names[a] = values[a].toString();
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ SimpleType.STRING,
+ null, names);
+ }
+ if (c.isArray())
+ {
+ int depth;
+ for (depth = 0; c.getName().charAt(depth) == '['; ++depth)
+ ;
+ OpenType<?> ot = getTypeFromClass(c.getComponentType());
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ new ArrayType<OpenType<?>>(depth, ot)
+ );
+ }
+ Method[] methods = c.getDeclaredMethods();
+ List<String> names = new ArrayList<String>();
+ List<OpenType<?>> types = new ArrayList<OpenType<?>>();
+ for (int a = 0; a < methods.length; ++a)
+ {
+ String name = methods[a].getName();
+ if (Modifier.isPublic(methods[a].getModifiers()))
+ {
+ if (name.startsWith("get"))
+ {
+ names.add(name.substring(3));
+ types.add(getTypeFromClass(methods[a].getReturnType()));
+ }
+ else if (name.startsWith("is"))
+ {
+ names.add(name.substring(2));
+ types.add(getTypeFromClass(methods[a].getReturnType()));
+ }
+ }
+ }
+ if (names.isEmpty())
+ throw new OpenDataException("The type used does not have an open type translation.");
+ String[] fields = names.toArray(new String[names.size()]);
+ CompositeType ctype = new CompositeType(c.getName(), c.getName(),
+ fields, fields,
+ types.toArray(new OpenType[types.size()]));
+ return new OpenMBeanParameterInfoSupport("TransParam",
+ "Translated parameter",
+ ctype);
+ }
+
+ /**
+ * Obtains the {@link javax.management.openmbean.OpenType}
+ * for a particular class.
+ *
+ * @param c the class to obtain the type for.
+ * @return the appropriate instance.
+ * @throws OpenDataException if the type is not open.
+ */
+ private static final OpenType<?> getTypeFromClass(Class<?> c)
+ throws OpenDataException
+ {
+ return Translator.translate(c.getName()).getOpenType();
+ }
+
+ /**
+ * <p>
+ * Returns the type name according to the rules described
+ * in {@link javax.management.MXBean}. Namely, for a type,
+ * {@code T}, {@code typename(T)} is computed as follows:
+ * </p>
+ * <ul>
+ * <li>If T is non-generic and not an array, then the value
+ * of {@link java.lang.Class#getName()} is returned.</li>
+ * <li>If T is an array type, {@code{E[]}, then the type name
+ * is {@code typename(E)} followed by an occurrence
+ * of {@code '[]'} for each dimension.</li>
+ * <li>If T is a generic or parameterized type, the type name
+ * is composed of {@code typename(P)}, where {@code P} is the
+ * parameterized type name, followed by {@code '<'}, the resulting
+ * list of type names of the parameters after applying {@code typename}
+ * to each, separated by commas, and {@code '>'}.</li>
+ * </ul>
+ *
+ * @param type the type to return the type name of.
+ * @return the type name computed according to the rules above.
+ */
+ private static final String getTypeName(Type type)
+ {
+ if (type instanceof Class)
+ {
+ Class<?> c = (Class<?>) type;
+ if (c.isArray())
+ {
+ StringBuilder b =
+ new StringBuilder(c.getComponentType().getName());
+ String normName = c.getName();
+ for (int a = 0; a < normName.length(); ++a)
+ {
+ if (normName.charAt(a) == '[')
+ b.append("[]");
+ else
+ break;
+ }
+ return b.toString();
+ }
+ return c.getName();
+ }
+ return type.toString();
+ }
+
+}