jdk/src/share/classes/com/sun/jmx/namespace/HandlerInterceptor.java
author dfuchs
Thu, 04 Sep 2008 14:46:36 +0200
changeset 1156 bbc2d15aaf7a
child 1222 78e3d021d528
permissions -rw-r--r--
5072476: RFE: support cascaded (federated) MBean Servers 6299231: Add support for named MBean Servers Summary: New javax.management.namespace package. Reviewed-by: emcmanus

/*
 * 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 com.sun.jmx.namespace;


import com.sun.jmx.defaults.JmxProperties;
import com.sun.jmx.interceptor.MBeanServerInterceptor;

import com.sun.jmx.mbeanserver.Util;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

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.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.RuntimeOperationsException;
import javax.management.loading.ClassLoaderRepository;
import javax.management.namespace.JMXNamespace;

/**
 * This interceptor wraps a JMXNamespace, and performs
 * {@code ObjectName} rewriting. {@code HandlerInterceptor} are
 * usually created and managed by a {@link NamespaceDispatcher} or
 * {@link DomainDispatcher}.
 * <p><b>
 * This API is a Sun internal API and is subject to changes without notice.
 * </b></p>
 * @since 1.7
 */
public abstract class HandlerInterceptor<T extends JMXNamespace>
        extends RoutingMBeanServerConnection<MBeanServer>
        implements MBeanServerInterceptor {

    /**
     * A logger for this class.
     **/
    private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;

    // The wrapped JMXNamespace
    private final T handler;

    /**
     * Creates a new instance of HandlerInterceptor
     */
    public HandlerInterceptor(T handler) {
        if (handler == null) throw new IllegalArgumentException("null");
        this.handler = handler;
    }

    @Override
    protected MBeanServer source() {
         return handler.getSourceServer();
    }

    // The MBeanServer on which getClassLoader / getClassLoaderFor
    // will be called.
    // The NamespaceInterceptor overrides this method - so that it
    // getClassLoader / getClassLoaderFor don't trigger the loop
    // detection mechanism.
    //
    MBeanServer getServerForLoading() {
         return source();
    }

    T getNamespace() {
        return handler;
    }

    // If the underlying JMXNamespace throws an IO, the IO will be
    // wrapped in a RuntimeOperationsException.
    RuntimeException handleIOException(IOException x,String fromMethodName,
            Object... params) {
            // Must do something here?
        if (LOG.isLoggable(Level.FINEST)) {
            LOG.finest("IO Exception in "+fromMethodName+": "+x+
                    " - "+" rethrowing as RuntimeOperationsException.");
        }
        throw new RuntimeOperationsException(
                    Util.newRuntimeIOException(x));
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public AttributeList getAttributes(ObjectName name, String[] attributes)
        throws InstanceNotFoundException, ReflectionException {
        try {
            return super.getAttributes(name, attributes);
        } catch (IOException ex) {
            throw handleIOException(ex,"getAttributes",name,attributes);
        }
    }

    // From MBeanServer
    public ClassLoader getClassLoaderFor(ObjectName mbeanName)
        throws InstanceNotFoundException {
        final ObjectName sourceName = toSourceOrRuntime(mbeanName);
        try {
            check(mbeanName,null,"getClassLoaderFor");
            return getServerForLoading().getClassLoaderFor(sourceName);
        } catch (RuntimeException ex) {
            throw makeCompliantRuntimeException(ex);
        }
    }


    // From MBeanServer
    public ClassLoader getClassLoader(ObjectName loaderName)
        throws InstanceNotFoundException {
        final ObjectName sourceName = toSourceOrRuntime(loaderName);
        try {
            check(loaderName,null,"getClassLoader");
            return getServerForLoading().getClassLoader(sourceName);
        } catch (RuntimeException ex) {
            throw makeCompliantRuntimeException(ex);
        }
    }

    // From MBeanServer
    public ObjectInstance registerMBean(Object object, ObjectName name)
        throws InstanceAlreadyExistsException, MBeanRegistrationException,
            NotCompliantMBeanException {
        final ObjectName sourceName = newSourceMBeanName(name);
        try {
            checkCreate(name,object.getClass().getName(),"registerMBean");
            return processOutputInstance(
                    source().registerMBean(object,sourceName));
        } catch (RuntimeException ex) {
            throw makeCompliantRuntimeException(ex);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public void removeNotificationListener(ObjectName name, ObjectName listener)
        throws InstanceNotFoundException, ListenerNotFoundException {
        try {
            super.removeNotificationListener(name, listener);
        } catch (IOException ex) {
            throw handleIOException(ex,"removeNotificationListener",name,listener);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public String getDefaultDomain() {
        try {
            return super.getDefaultDomain();
        } catch (IOException ex) {
            throw handleIOException(ex,"getDefaultDomain");
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public String[] getDomains() {
        try {
            return super.getDomains();
        } catch (IOException ex) {
            throw handleIOException(ex,"getDomains");
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public Integer getMBeanCount() {
        try {
            return super.getMBeanCount();
        } catch (IOException ex) {
            throw handleIOException(ex,"getMBeanCount");
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public void setAttribute(ObjectName name, Attribute attribute)
        throws InstanceNotFoundException, AttributeNotFoundException,
            InvalidAttributeValueException, MBeanException,
            ReflectionException {
        try {
            super.setAttribute(name, attribute);
        } catch (IOException ex) {
            throw handleIOException(ex,"setAttribute",name, attribute);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
        try {
            return super.queryNames(name, query);
        } catch (IOException ex) {
            throw handleIOException(ex,"queryNames",name, query);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
        try {
            return super.queryMBeans(name, query);
        } catch (IOException ex) {
            throw handleIOException(ex,"queryMBeans",name, query);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public boolean isInstanceOf(ObjectName name, String className)
        throws InstanceNotFoundException {
        try {
            return super.isInstanceOf(name, className);
        } catch (IOException ex) {
            throw handleIOException(ex,"isInstanceOf",name, className);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public ObjectInstance createMBean(String className, ObjectName name)
        throws ReflectionException, InstanceAlreadyExistsException,
            MBeanRegistrationException, MBeanException,
            NotCompliantMBeanException {
        try {
            return super.createMBean(className, name);
        } catch (IOException ex) {
            throw handleIOException(ex,"createMBean",className, name);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public ObjectInstance createMBean(String className, ObjectName name,
                        ObjectName loaderName)
        throws ReflectionException, InstanceAlreadyExistsException,
                MBeanRegistrationException, MBeanException,
                NotCompliantMBeanException, InstanceNotFoundException {
        try {
            return super.createMBean(className, name, loaderName);
        } catch (IOException ex) {
            throw handleIOException(ex,"createMBean",className, name, loaderName);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public Object getAttribute(ObjectName name, String attribute)
        throws MBeanException, AttributeNotFoundException,
            InstanceNotFoundException, ReflectionException {
        try {
            return super.getAttribute(name, attribute);
        } catch (IOException ex) {
            throw handleIOException(ex,"getAttribute",name, attribute);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public void removeNotificationListener(ObjectName name, ObjectName listener,
                            NotificationFilter filter, Object handback)
        throws InstanceNotFoundException, ListenerNotFoundException {
        try {
            super.removeNotificationListener(name, listener, filter, handback);
        } catch (IOException ex) {
            throw handleIOException(ex,"removeNotificationListener",name,
                    listener, filter, handback);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public void removeNotificationListener(ObjectName name,
                      NotificationListener listener, NotificationFilter filter,
                      Object handback)
        throws InstanceNotFoundException, ListenerNotFoundException {
        try {
            super.removeNotificationListener(name, listener, filter, handback);
        } catch (IOException ex) {
            throw handleIOException(ex,"removeNotificationListener",name,
                    listener, filter, handback);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public void removeNotificationListener(ObjectName name,
                NotificationListener listener)
        throws InstanceNotFoundException, ListenerNotFoundException {
        try {
            super.removeNotificationListener(name, listener);
        } catch (IOException ex) {
            throw handleIOException(ex,"removeNotificationListener",name,
                    listener);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public void addNotificationListener(ObjectName name,
                    NotificationListener listener, NotificationFilter filter,
                    Object handback) throws InstanceNotFoundException {
        try {
            super.addNotificationListener(name, listener, filter, handback);
        } catch (IOException ex) {
            throw handleIOException(ex,"addNotificationListener",name,
                    listener, filter, handback);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public void addNotificationListener(ObjectName name, ObjectName listener,
                NotificationFilter filter, Object handback)
        throws InstanceNotFoundException {
        try {
            super.addNotificationListener(name, listener, filter, handback);
        } catch (IOException ex) {
            throw handleIOException(ex,"addNotificationListener",name,
                    listener, filter, handback);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public boolean isRegistered(ObjectName name) {
        try {
            return super.isRegistered(name);
        } catch (IOException ex) {
            throw handleIOException(ex,"isRegistered",name);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public void unregisterMBean(ObjectName name)
        throws InstanceNotFoundException, MBeanRegistrationException {
        try {
            super.unregisterMBean(name);
        } catch (IOException ex) {
            throw handleIOException(ex,"unregisterMBean",name);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public MBeanInfo getMBeanInfo(ObjectName name)
        throws InstanceNotFoundException, IntrospectionException,
            ReflectionException {
        try {
            return super.getMBeanInfo(name);
        } catch (IOException ex) {
            throw handleIOException(ex,"getMBeanInfo",name);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public ObjectInstance getObjectInstance(ObjectName name)
        throws InstanceNotFoundException {
        try {
            return super.getObjectInstance(name);
        } catch (IOException ex) {
            throw handleIOException(ex,"getObjectInstance",name);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public ObjectInstance createMBean(String className, ObjectName name,
                Object[] params, String[] signature)
        throws ReflectionException, InstanceAlreadyExistsException,
            MBeanRegistrationException, MBeanException,
            NotCompliantMBeanException {
        try {
            return super.createMBean(className, name, params, signature);
        } catch (IOException ex) {
            throw handleIOException(ex,"createMBean",className, name,
                    params, signature);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public ObjectInstance createMBean(String className, ObjectName name,
                ObjectName loaderName, Object[] params, String[] signature)
        throws ReflectionException, InstanceAlreadyExistsException,
            MBeanRegistrationException, MBeanException,
            NotCompliantMBeanException, InstanceNotFoundException {
        try {
            return super.createMBean(className, name, loaderName, params,
                    signature);
        } catch (IOException ex) {
            throw handleIOException(ex,"createMBean",className, name,loaderName,
                    params, signature);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public AttributeList setAttributes(ObjectName name,AttributeList attributes)
    throws InstanceNotFoundException, ReflectionException {
        try {
            return super.setAttributes(name, attributes);
        } catch (IOException ex) {
            throw handleIOException(ex,"setAttributes",name, attributes);
        }
    }

    // From MBeanServer: catch & handles IOException
    @Override
    public Object invoke(ObjectName name, String operationName, Object[] params,
                String[] signature)
        throws InstanceNotFoundException, MBeanException, ReflectionException {
        try {
            return super.invoke(name, operationName, params, signature);
        } catch (IOException ex) {
            throw handleIOException(ex,"invoke",name, operationName,
                    params, signature);
        }
    }

    //
    //  These methods are inherited from MBeanServer....
    //

    /**
     * This method should never be called.
     * Throws UnsupportedOperationException.
     */
    public Object instantiate(String className)
            throws ReflectionException, MBeanException {
        if (LOG.isLoggable(Level.FINE))
            LOG.fine("call to unsupported instantiate method: " +
                    "trowing UnsupportedOperationException");
        throw new UnsupportedOperationException("Not applicable.");
    }

    /**
     * This method should never be called.
     * Throws UnsupportedOperationException.
     */
    public Object instantiate(String className, ObjectName loaderName)
            throws ReflectionException, MBeanException,
            InstanceNotFoundException {
        if (LOG.isLoggable(Level.FINE))
            LOG.fine("call to unsupported method: instantiate(...) -" +
                    "throwing UnsupportedOperationException");
        throw new UnsupportedOperationException("Not applicable.");
    }

    /**
     * This method should never be called.
     * Throws UnsupportedOperationException.
     */
    public Object instantiate(String className, Object[] params,
            String[] signature) throws ReflectionException, MBeanException {
        if (LOG.isLoggable(Level.FINE))
            LOG.fine("call to unsupported method: instantiate(...) -" +
                    "throwing UnsupportedOperationException");
        throw new UnsupportedOperationException("Not applicable.");
    }

    /**
     * This method should never be called.
     * Throws UnsupportedOperationException.
     */
    public Object instantiate(String className, ObjectName loaderName,
            Object[] params, String[] signature)
            throws ReflectionException, MBeanException,
            InstanceNotFoundException {
        if (LOG.isLoggable(Level.FINE))
            LOG.fine("call to unsupported method: instantiate(...) -" +
                    "throwing UnsupportedOperationException");
        throw new UnsupportedOperationException("Not applicable.");
    }

    /**
     * This method should never be called.
     * Throws UnsupportedOperationException.
     */
    @Deprecated
    public ObjectInputStream deserialize(ObjectName name, byte[] data)
            throws InstanceNotFoundException, OperationsException {
        if (LOG.isLoggable(Level.FINE))
            LOG.fine("call to unsupported method: deserialize(...) -" +
                    "throwing UnsupportedOperationException");
        throw new UnsupportedOperationException("Not applicable.");
    }

    /**
     * This method should never be called.
     * Throws UnsupportedOperationException.
     */
    @Deprecated
    public ObjectInputStream deserialize(String className, byte[] data)
            throws OperationsException, ReflectionException {
        if (LOG.isLoggable(Level.FINE))
            LOG.fine("call to unsupported method: deserialize(...) -" +
                    "throwing UnsupportedOperationException");
        throw new UnsupportedOperationException("Not applicable.");
    }

    /**
     * This method should never be called.
     * Throws UnsupportedOperationException.
     */
    @Deprecated
    public ObjectInputStream deserialize(String className,
            ObjectName loaderName, byte[] data)
            throws InstanceNotFoundException, OperationsException,
            ReflectionException {
        if (LOG.isLoggable(Level.FINE))
            LOG.fine("call to unsupported method: deserialize(...) -" +
                    "throwing UnsupportedOperationException");
        throw new UnsupportedOperationException("Not applicable.");
    }

    /**
     * This method should never be called.
     * Throws UnsupportedOperationException.
     */
    public ClassLoaderRepository getClassLoaderRepository() {
        if (LOG.isLoggable(Level.FINE))
            LOG.fine("call to unsupported method: getClassLoaderRepository() -" +
                    "throwing UnsupportedOperationException");
        throw new UnsupportedOperationException("Not applicable.");
    }

    static RuntimeException newUnsupportedException(String namespace) {
        return new RuntimeOperationsException(
            new UnsupportedOperationException(
                "Not supported in this namespace: "+namespace));
    }

}