--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java Thu Sep 04 14:46:36 2008 +0200
@@ -0,0 +1,703 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management.namespace;
+
+import com.sun.jmx.mbeanserver.Util;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.security.AccessController;
+import java.util.Set;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerConnection;
+import javax.management.NotCompliantMBeanException;
+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.loading.ClassLoaderRepository;
+
+/**
+ * <p>An object of this class implements the MBeanServer interface
+ * and, for each of its methods forwards the request to a wrapped
+ * {@link MBeanServerConnection} object.
+ * Some methods of the {@link MBeanServer} interface do not have
+ * any equivalent in {@link MBeanServerConnection}. In that case, an
+ * {@link UnsupportedOperationException} will be thrown.
+ *
+ * <p>A typical use of this class is to apply a {@link QueryExp} object locally,
+ * on an MBean that resides in a remote MBeanServer. Since an
+ * MBeanServerConnection is not an MBeanServer, it cannot be passed
+ * to the <code>setMBeanServer()</code> method of the {@link QueryExp}
+ * object. However, this object can.</p>
+ *
+ * @since 1.7
+ */
+public class MBeanServerConnectionWrapper
+ implements MBeanServer {
+
+ private final MBeanServerConnection wrapped;
+ private final ClassLoader defaultCl;
+
+ /**
+ * Construct a new object that implements {@link MBeanServer} by
+ * forwarding its methods to the given {@link MBeanServerConnection}.
+ * This constructor is equivalent to {@link #MBeanServerConnectionWrapper(
+ * MBeanServerConnection, ClassLoader) MBeanServerConnectionWrapper(wrapped,
+ * null)}.
+ *
+ * @param wrapped the {@link MBeanServerConnection} to which methods
+ * are to be forwarded. This parameter can be null, in which case the
+ * {@code MBeanServerConnection} will typically be supplied by overriding
+ * {@link #getMBeanServerConnection}.
+ */
+ public MBeanServerConnectionWrapper(MBeanServerConnection wrapped) {
+ this(wrapped, null);
+ }
+
+ /**
+ * Construct a new object that implements {@link MBeanServer} by
+ * forwarding its methods to the given {@link MBeanServerConnection}.
+ * The {@code defaultCl} parameter specifies the value to be returned
+ * by {@link #getDefaultClassLoader}. A null value is equivalent to
+ * {@link Thread#getContextClassLoader()}.
+ *
+ * @param wrapped the {@link MBeanServerConnection} to which methods
+ * are to be forwarded. This parameter can be null, in which case the
+ * {@code MBeanServerConnection} will typically be supplied by overriding
+ * {@link #getMBeanServerConnection}.
+ * @param defaultCl the value to be returned by {@link
+ * #getDefaultClassLoader}. A null value is equivalent to the current
+ * thread's {@linkplain Thread#getContextClassLoader()}.
+ */
+ public MBeanServerConnectionWrapper(MBeanServerConnection wrapped,
+ ClassLoader defaultCl) {
+ this.wrapped = wrapped;
+ this.defaultCl = (defaultCl == null) ?
+ Thread.currentThread().getContextClassLoader() : defaultCl;
+ }
+
+ /**
+ * Returns an MBeanServerConnection. This method is called each time
+ * an operation must be invoked on the underlying MBeanServerConnection.
+ * The default implementation returns the MBeanServerConnection that
+ * was supplied to the constructor of this MBeanServerConnectionWrapper.
+ **/
+ protected MBeanServerConnection getMBeanServerConnection() {
+ return wrapped;
+ }
+
+ /**
+ * Returns the default class loader passed to the constructor. If the
+ * value passed was null, then the returned value will be the
+ * {@linkplain Thread#getContextClassLoader() context class loader} at the
+ * time this object was constructed.
+ *
+ * @return the ClassLoader that was passed to the constructor.
+ **/
+ public ClassLoader getDefaultClassLoader() {
+ return defaultCl;
+ }
+
+ /**
+ * <p>This method is called each time an IOException is raised when
+ * trying to forward an operation to the underlying
+ * MBeanServerConnection, as a result of calling
+ * {@link #getMBeanServerConnection()} or as a result of invoking the
+ * operation on the returned connection. Since the methods in
+ * {@link MBeanServer} are not declared to throw {@code IOException},
+ * this method must return a {@code RuntimeException} to be thrown
+ * instead. Typically, the original {@code IOException} will be in the
+ * {@linkplain Throwable#getCause() cause chain} of the {@code
+ * RuntimeException}.</p>
+ *
+ * <p>Subclasses may redefine this method if they need to perform any
+ * specific handling of IOException (logging etc...).</p>
+ *
+ * @param x The raised IOException.
+ * @param method The name of the method in which the exception was
+ * raised. This is one of the methods of the MBeanServer
+ * interface.
+ *
+ * @return A RuntimeException that should be thrown by the caller.
+ * In this default implementation, this is a
+ * {@link RuntimeException} wrapping <var>x</var>.
+ **/
+ protected RuntimeException wrapIOException(IOException x, String method) {
+ return Util.newRuntimeIOException(x);
+ }
+
+ // Take care of getMBeanServerConnection returning null.
+ //
+ private synchronized MBeanServerConnection connection()
+ throws IOException {
+ final MBeanServerConnection c = getMBeanServerConnection();
+ if (c == null)
+ throw new IOException("MBeanServerConnection unavailable");
+ return c;
+ }
+
+ //--------------------------------------------
+ //--------------------------------------------
+ //
+ // Implementation of the MBeanServer interface
+ //
+ //--------------------------------------------
+ //--------------------------------------------
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public void addNotificationListener(ObjectName name,
+ NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws InstanceNotFoundException {
+ try {
+ connection().addNotificationListener(name, listener,
+ filter, handback);
+ } catch (IOException x) {
+ throw wrapIOException(x,"addNotificationListener");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public void addNotificationListener(ObjectName name,
+ ObjectName listener,
+ NotificationFilter filter,
+ Object handback)
+ throws InstanceNotFoundException {
+ try {
+ connection().addNotificationListener(name, listener,
+ filter, handback);
+ } catch (IOException x) {
+ throw wrapIOException(x,"addNotificationListener");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public ObjectInstance createMBean(String className, ObjectName name)
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException {
+ try {
+ return connection().createMBean(className, name);
+ } catch (IOException x) {
+ throw wrapIOException(x,"createMBean");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public ObjectInstance createMBean(String className, ObjectName name,
+ Object params[], String signature[])
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException {
+ try {
+ return connection().createMBean(className, name,
+ params, signature);
+ } catch (IOException x) {
+ throw wrapIOException(x,"createMBean");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ ObjectName loaderName)
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ InstanceNotFoundException {
+ try {
+ return connection().createMBean(className, name, loaderName);
+ } catch (IOException x) {
+ throw wrapIOException(x,"createMBean");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ ObjectName loaderName,
+ Object params[],
+ String signature[])
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ InstanceNotFoundException {
+ try {
+ return connection().createMBean(className, name, loaderName,
+ params, signature);
+ } catch (IOException x) {
+ throw wrapIOException(x,"createMBean");
+ }
+ }
+
+ /**
+ * Throws an {@link UnsupportedOperationException}. This behavior can
+ * be changed by subclasses.
+ * @deprecated see {@link MBeanServer#deserialize(ObjectName,byte[])
+ * MBeanServer}
+ */
+ @Deprecated
+ public ObjectInputStream deserialize(ObjectName name, byte[] data)
+ throws InstanceNotFoundException, OperationsException {
+ throw new UnsupportedOperationException("deserialize");
+ }
+
+ /**
+ * Throws an {@link UnsupportedOperationException}. This behavior can
+ * be changed by subclasses.
+ * @deprecated see {@link MBeanServer#deserialize(String,byte[])
+ * MBeanServer}
+ */
+ @Deprecated
+ public ObjectInputStream deserialize(String className, byte[] data)
+ throws OperationsException, ReflectionException {
+ throw new UnsupportedOperationException("deserialize");
+ }
+
+ /**
+ * Throws an {@link UnsupportedOperationException}. This behavior can
+ * be changed by subclasses.
+ * @deprecated see {@link MBeanServer#deserialize(String,ObjectName,byte[])
+ * MBeanServer}
+ */
+ @Deprecated
+ public ObjectInputStream deserialize(String className,
+ ObjectName loaderName,
+ byte[] data)
+ throws
+ InstanceNotFoundException,
+ OperationsException,
+ ReflectionException {
+ throw new UnsupportedOperationException("deserialize");
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public Object getAttribute(ObjectName name, String attribute)
+ throws
+ MBeanException,
+ AttributeNotFoundException,
+ InstanceNotFoundException,
+ ReflectionException {
+ try {
+ return connection().getAttribute(name, attribute);
+ } catch (IOException x) {
+ throw wrapIOException(x,"getAttribute");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public AttributeList getAttributes(ObjectName name, String[] attributes)
+ throws InstanceNotFoundException, ReflectionException {
+ try {
+ return connection().getAttributes(name, attributes);
+ } catch (IOException x) {
+ throw wrapIOException(x,"getAttributes");
+ }
+ }
+
+ /**
+ * Throws an {@link UnsupportedOperationException}. This behavior can
+ * be changed by subclasses.
+ */
+ public ClassLoader getClassLoader(ObjectName loaderName)
+ throws InstanceNotFoundException {
+ throw new UnsupportedOperationException("getClassLoader");
+ }
+
+ /**
+ * Returns the {@linkplain #getDefaultClassLoader() default class loader}.
+ * This behavior can be changed by subclasses.
+ */
+ public ClassLoader getClassLoaderFor(ObjectName mbeanName)
+ throws InstanceNotFoundException {
+ return getDefaultClassLoader();
+ }
+
+ /**
+ * <p>Returns a {@link ClassLoaderRepository} based on the class loader
+ * returned by {@link #getDefaultClassLoader()}.</p>
+ * @return a {@link ClassLoaderRepository} that contains a single
+ * class loader, returned by {@link #getDefaultClassLoader()}.
+ **/
+ public ClassLoaderRepository getClassLoaderRepository() {
+ // We return a new ClassLoaderRepository each time this method is
+ // called. This is by design, because there's no guarantee that
+ // getDefaultClassLoader() will always return the same class loader.
+ return Util.getSingleClassLoaderRepository(getDefaultClassLoader());
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public String getDefaultDomain() {
+ try {
+ return connection().getDefaultDomain();
+ } catch (IOException x) {
+ throw wrapIOException(x,"getDefaultDomain");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public String[] getDomains() {
+ try {
+ return connection().getDomains();
+ } catch (IOException x) {
+ throw wrapIOException(x,"getDomains");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public Integer getMBeanCount() {
+ try {
+ return connection().getMBeanCount();
+ } catch (IOException x) {
+ throw wrapIOException(x,"getMBeanCount");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public MBeanInfo getMBeanInfo(ObjectName name)
+ throws
+ InstanceNotFoundException,
+ IntrospectionException,
+ ReflectionException {
+ try {
+ return connection().getMBeanInfo(name);
+ } catch (IOException x) {
+ throw wrapIOException(x,"getMBeanInfo");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public ObjectInstance getObjectInstance(ObjectName name)
+ throws InstanceNotFoundException {
+ try {
+ return connection().getObjectInstance(name);
+ } catch (IOException x) {
+ throw wrapIOException(x,"getObjectInstance");
+ }
+ }
+
+ /**
+ * Throws an {@link UnsupportedOperationException}. This behavior can
+ * be changed by subclasses.
+ */
+ public Object instantiate(String className)
+ throws ReflectionException, MBeanException {
+ throw new UnsupportedOperationException("instantiate");
+ }
+
+ /**
+ * Throws an {@link UnsupportedOperationException}. This behavior can
+ * be changed by subclasses.
+ */
+ public Object instantiate(String className,
+ Object params[],
+ String signature[])
+ throws ReflectionException, MBeanException {
+ throw new UnsupportedOperationException("instantiate");
+ }
+
+ /**
+ * Throws an {@link UnsupportedOperationException}. This behavior can
+ * be changed by subclasses.
+ */
+ public Object instantiate(String className, ObjectName loaderName)
+ throws ReflectionException, MBeanException,
+ InstanceNotFoundException {
+ throw new UnsupportedOperationException("instantiate");
+ }
+
+ /**
+ * Throws an {@link UnsupportedOperationException}. This behavior can
+ * be changed by subclasses.
+ */
+ public Object instantiate(String className, ObjectName loaderName,
+ Object params[], String signature[])
+ throws ReflectionException, MBeanException,
+ InstanceNotFoundException {
+ throw new UnsupportedOperationException("instantiate");
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public Object invoke(ObjectName name, String operationName,
+ Object params[], String signature[])
+ throws
+ InstanceNotFoundException,
+ MBeanException,
+ ReflectionException {
+ try {
+ return connection().invoke(name,operationName,params,signature);
+ } catch (IOException x) {
+ throw wrapIOException(x,"invoke");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public boolean isInstanceOf(ObjectName name, String className)
+ throws InstanceNotFoundException {
+ try {
+ return connection().isInstanceOf(name, className);
+ } catch (IOException x) {
+ throw wrapIOException(x,"isInstanceOf");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public boolean isRegistered(ObjectName name) {
+ try {
+ return connection().isRegistered(name);
+ } catch (IOException x) {
+ throw wrapIOException(x,"isRegistered");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ * If an IOException is raised, returns an empty Set.
+ */
+ public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
+ try {
+ return connection().queryMBeans(name, query);
+ } catch (IOException x) {
+ throw wrapIOException(x,"queryMBeans");
+ //return Collections.emptySet();
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ * If an IOException is raised, returns an empty Set.
+ */
+ public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
+ try {
+ return connection().queryNames(name, query);
+ } catch (IOException x) {
+ throw wrapIOException(x,"queryNames");
+ //return Collections.emptySet();
+ }
+ }
+
+ /**
+ * Throws an {@link UnsupportedOperationException}. This behavior can
+ * be changed by subclasses.
+ */
+ public ObjectInstance registerMBean(Object object, ObjectName name)
+ throws
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ NotCompliantMBeanException {
+ throw new UnsupportedOperationException("registerMBean");
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public void removeNotificationListener(ObjectName name,
+ NotificationListener listener)
+ throws InstanceNotFoundException, ListenerNotFoundException {
+ try {
+ connection().removeNotificationListener(name, listener);
+ } catch (IOException x) {
+ throw wrapIOException(x,"removeNotificationListener");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public void removeNotificationListener(ObjectName name,
+ NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws InstanceNotFoundException, ListenerNotFoundException {
+ try {
+ connection().removeNotificationListener(name, listener,
+ filter, handback);
+ } catch (IOException x) {
+ throw wrapIOException(x,"removeNotificationListener");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public void removeNotificationListener(ObjectName name,
+ ObjectName listener)
+ throws InstanceNotFoundException, ListenerNotFoundException {
+ try {
+ connection().removeNotificationListener(name, listener);
+ } catch (IOException x) {
+ throw wrapIOException(x,"removeNotificationListener");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public void removeNotificationListener(ObjectName name,
+ ObjectName listener,
+ NotificationFilter filter,
+ Object handback)
+ throws InstanceNotFoundException, ListenerNotFoundException {
+ try {
+ connection().removeNotificationListener(name, listener,
+ filter, handback);
+ } catch (IOException x) {
+ throw wrapIOException(x,"removeNotificationListener");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public void setAttribute(ObjectName name, Attribute attribute)
+ throws
+ InstanceNotFoundException,
+ AttributeNotFoundException,
+ InvalidAttributeValueException,
+ MBeanException,
+ ReflectionException {
+ try {
+ connection().setAttribute(name, attribute);
+ } catch (IOException x) {
+ throw wrapIOException(x,"setAttribute");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public AttributeList setAttributes(ObjectName name,
+ AttributeList attributes)
+ throws InstanceNotFoundException, ReflectionException {
+ try {
+ return connection().setAttributes(name, attributes);
+ } catch (IOException x) {
+ throw wrapIOException(x,"setAttributes");
+ }
+ }
+
+ /**
+ * Forward this method to the
+ * wrapped object.
+ */
+ public void unregisterMBean(ObjectName name)
+ throws InstanceNotFoundException, MBeanRegistrationException {
+ try {
+ connection().unregisterMBean(name);
+ } catch (IOException x) {
+ throw wrapIOException(x,"unregisterMBean");
+ }
+ }
+
+ //----------------
+ // PRIVATE METHODS
+ //----------------
+
+}