/*
 * Copyright (c) 2005, 2006, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.management;

import com.sun.jmx.mbeanserver.Introspector;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * Static methods from the JMX API.  There are no instances of this class.
 *
 * @since 1.6
 */
public class JMX {
    /* Code within this package can prove that by providing this instance of
     * this class.
     */
    static final JMX proof = new JMX();

    private JMX() {}

    /**
     * The name of the <a href="Descriptor.html#defaultValue">{@code
     * defaultValue}</a> field.
     */
    public static final String DEFAULT_VALUE_FIELD = "defaultValue";

    /**
     * The name of the <a href="Descriptor.html#immutableInfo">{@code
     * immutableInfo}</a> field.
     */
    public static final String IMMUTABLE_INFO_FIELD = "immutableInfo";

    /**
     * The name of the <a href="Descriptor.html#interfaceClassName">{@code
     * interfaceClassName}</a> field.
     */
    public static final String INTERFACE_CLASS_NAME_FIELD = "interfaceClassName";

    /**
     * The name of the <a href="Descriptor.html#legalValues">{@code
     * legalValues}</a> field.
     */
    public static final String LEGAL_VALUES_FIELD = "legalValues";

    /**
     * The name of the <a href="Descriptor.html#maxValue">{@code
     * maxValue}</a> field.
     */
    public static final String MAX_VALUE_FIELD = "maxValue";

    /**
     * The name of the <a href="Descriptor.html#minValue">{@code
     * minValue}</a> field.
     */
    public static final String MIN_VALUE_FIELD = "minValue";

    /**
     * The name of the <a href="Descriptor.html#mxbean">{@code
     * mxbean}</a> field.
     */
    public static final String MXBEAN_FIELD = "mxbean";

    /**
     * The name of the <a href="Descriptor.html#openType">{@code
     * openType}</a> field.
     */
    public static final String OPEN_TYPE_FIELD = "openType";

    /**
     * The name of the <a href="Descriptor.html#originalType">{@code
     * originalType}</a> field.
     */
    public static final String ORIGINAL_TYPE_FIELD = "originalType";

    /**
     * <p>Make a proxy for a Standard MBean in a local or remote
     * MBean Server.</p>
     *
     * <p>If you have an MBean Server {@code mbs} containing an MBean
     * with {@link ObjectName} {@code name}, and if the MBean's
     * management interface is described by the Java interface
     * {@code MyMBean}, you can construct a proxy for the MBean like
     * this:</p>
     *
     * <pre>
     * MyMBean proxy = JMX.newMBeanProxy(mbs, name, MyMBean.class);
     * </pre>
     *
     * <p>Suppose, for example, {@code MyMBean} looks like this:</p>
     *
     * <pre>
     * public interface MyMBean {
     *     public String getSomeAttribute();
     *     public void setSomeAttribute(String value);
     *     public void someOperation(String param1, int param2);
     * }
     * </pre>
     *
     * <p>Then you can execute:</p>
     *
     * <ul>
     *
     * <li>{@code proxy.getSomeAttribute()} which will result in a
     * call to {@code mbs.}{@link MBeanServerConnection#getAttribute
     * getAttribute}{@code (name, "SomeAttribute")}.
     *
     * <li>{@code proxy.setSomeAttribute("whatever")} which will result
     * in a call to {@code mbs.}{@link MBeanServerConnection#setAttribute
     * setAttribute}{@code (name, new Attribute("SomeAttribute", "whatever"))}.
     *
     * <li>{@code proxy.someOperation("param1", 2)} which will be
     * translated into a call to {@code mbs.}{@link
     * MBeanServerConnection#invoke invoke}{@code (name, "someOperation", <etc>)}.
     *
     * </ul>
     *
     * <p>The object returned by this method is a
     * {@link Proxy} whose {@code InvocationHandler} is an
     * {@link MBeanServerInvocationHandler}.</p>
     *
     * <p>This method is equivalent to {@link
     * #newMBeanProxy(MBeanServerConnection, ObjectName, Class,
     * boolean) newMBeanProxy(connection, objectName, interfaceClass,
     * false)}.</p>
     *
     * @param connection the MBean server to forward to.
     * @param objectName the name of the MBean within
     * {@code connection} to forward to.
     * @param interfaceClass the management interface that the MBean
     * exports, which will also be implemented by the returned proxy.
     *
     * @param <T> allows the compiler to know that if the {@code
     * interfaceClass} parameter is {@code MyMBean.class}, for
     * example, then the return type is {@code MyMBean}.
     *
     * @return the new proxy instance.
     */
    public static <T> T newMBeanProxy(MBeanServerConnection connection,
                                      ObjectName objectName,
                                      Class<T> interfaceClass) {
        return newMBeanProxy(connection, objectName, interfaceClass, false);
    }

    /**
     * <p>Make a proxy for a Standard MBean in a local or remote MBean
     * Server that may also support the methods of {@link
     * NotificationEmitter}.</p>
     *
     * <p>This method behaves the same as {@link
     * #newMBeanProxy(MBeanServerConnection, ObjectName, Class)}, but
     * additionally, if {@code notificationEmitter} is {@code
     * true}, then the MBean is assumed to be a {@link
     * NotificationBroadcaster} or {@link NotificationEmitter} and the
     * returned proxy will implement {@link NotificationEmitter} as
     * well as {@code interfaceClass}.  A call to {@link
     * NotificationBroadcaster#addNotificationListener} on the proxy
     * will result in a call to {@link
     * MBeanServerConnection#addNotificationListener(ObjectName,
     * NotificationListener, NotificationFilter, Object)}, and
     * likewise for the other methods of {@link
     * NotificationBroadcaster} and {@link NotificationEmitter}.</p>
     *
     * @param connection the MBean server to forward to.
     * @param objectName the name of the MBean within
     * {@code connection} to forward to.
     * @param interfaceClass the management interface that the MBean
     * exports, which will also be implemented by the returned proxy.
     * @param notificationEmitter make the returned proxy
     * implement {@link NotificationEmitter} by forwarding its methods
     * via {@code connection}.
     *
     * @param <T> allows the compiler to know that if the {@code
     * interfaceClass} parameter is {@code MyMBean.class}, for
     * example, then the return type is {@code MyMBean}.
     *
     * @return the new proxy instance.
     */
    public static <T> T newMBeanProxy(MBeanServerConnection connection,
                                      ObjectName objectName,
                                      Class<T> interfaceClass,
                                      boolean notificationEmitter) {
        return MBeanServerInvocationHandler.newProxyInstance(
                connection,
                objectName,
                interfaceClass,
                notificationEmitter);
    }

    /**
     * <p>Make a proxy for an MXBean in a local or remote
     * MBean Server.</p>
     *
     * <p>If you have an MBean Server {@code mbs} containing an
     * MXBean with {@link ObjectName} {@code name}, and if the
     * MXBean's management interface is described by the Java
     * interface {@code MyMXBean}, you can construct a proxy for
     * the MXBean like this:</p>
     *
     * <pre>
     * MyMXBean proxy = JMX.newMXBeanProxy(mbs, name, MyMXBean.class);
     * </pre>
     *
     * <p>Suppose, for example, {@code MyMXBean} looks like this:</p>
     *
     * <pre>
     * public interface MyMXBean {
     *     public String getSimpleAttribute();
     *     public void setSimpleAttribute(String value);
     *     public {@link java.lang.management.MemoryUsage} getMappedAttribute();
     *     public void setMappedAttribute(MemoryUsage memoryUsage);
     *     public MemoryUsage someOperation(String param1, MemoryUsage param2);
     * }
     * </pre>
     *
     * <p>Then:</p>
     *
     * <ul>
     *
     * <li><p>{@code proxy.getSimpleAttribute()} will result in a
     * call to {@code mbs.}{@link MBeanServerConnection#getAttribute
     * getAttribute}{@code (name, "SimpleAttribute")}.</p>
     *
     * <li><p>{@code proxy.setSimpleAttribute("whatever")} will result
     * in a call to {@code mbs.}{@link
     * MBeanServerConnection#setAttribute setAttribute}<code>(name,
     * new Attribute("SimpleAttribute", "whatever"))</code>.<p>
     *
     *     <p>Because {@code String} is a <em>simple type</em>, in the
     *     sense of {@link javax.management.openmbean.SimpleType}, it
     *     is not changed in the context of an MXBean.  The MXBean
     *     proxy behaves the same as a Standard MBean proxy (see
     *     {@link #newMBeanProxy(MBeanServerConnection, ObjectName,
     *     Class) newMBeanProxy}) for the attribute {@code
     *     SimpleAttribute}.</p>
     *
     * <li><p>{@code proxy.getMappedAttribute()} will result in a call
     * to {@code mbs.getAttribute("MappedAttribute")}.  The MXBean
     * mapping rules mean that the actual type of the attribute {@code
     * MappedAttribute} will be {@link
     * javax.management.openmbean.CompositeData CompositeData} and
     * that is what the {@code mbs.getAttribute} call will return.
     * The proxy will then convert the {@code CompositeData} back into
     * the expected type {@code MemoryUsage} using the MXBean mapping
     * rules.</p>
     *
     * <li><p>Similarly, {@code proxy.setMappedAttribute(memoryUsage)}
     * will convert the {@code MemoryUsage} argument into a {@code
     * CompositeData} before calling {@code mbs.setAttribute}.</p>
     *
     * <li><p>{@code proxy.someOperation("whatever", memoryUsage)}
     * will convert the {@code MemoryUsage} argument into a {@code
     * CompositeData} and call {@code mbs.invoke}.  The value returned
     * by {@code mbs.invoke} will be also be a {@code CompositeData},
     * and the proxy will convert this into the expected type {@code
     * MemoryUsage} using the MXBean mapping rules.</p>
     *
     * </ul>
     *
     * <p>The object returned by this method is a
     * {@link Proxy} whose {@code InvocationHandler} is an
     * {@link MBeanServerInvocationHandler}.</p>
     *
     * <p>This method is equivalent to {@link
     * #newMXBeanProxy(MBeanServerConnection, ObjectName, Class,
     * boolean) newMXBeanProxy(connection, objectName, interfaceClass,
     * false)}.</p>
     *
     * @param connection the MBean server to forward to.
     * @param objectName the name of the MBean within
     * {@code connection} to forward to.
     * @param interfaceClass the MXBean interface,
     * which will also be implemented by the returned proxy.
     *
     * @param <T> allows the compiler to know that if the {@code
     * interfaceClass} parameter is {@code MyMXBean.class}, for
     * example, then the return type is {@code MyMXBean}.
     *
     * @return the new proxy instance.
     */
    public static <T> T newMXBeanProxy(MBeanServerConnection connection,
                                       ObjectName objectName,
                                       Class<T> interfaceClass) {
        return newMXBeanProxy(connection, objectName, interfaceClass, false);
    }

    /**
     * <p>Make a proxy for an MXBean in a local or remote MBean
     * Server that may also support the methods of {@link
     * NotificationEmitter}.</p>
     *
     * <p>This method behaves the same as {@link
     * #newMXBeanProxy(MBeanServerConnection, ObjectName, Class)}, but
     * additionally, if {@code notificationEmitter} is {@code
     * true}, then the MXBean is assumed to be a {@link
     * NotificationBroadcaster} or {@link NotificationEmitter} and the
     * returned proxy will implement {@link NotificationEmitter} as
     * well as {@code interfaceClass}.  A call to {@link
     * NotificationBroadcaster#addNotificationListener} on the proxy
     * will result in a call to {@link
     * MBeanServerConnection#addNotificationListener(ObjectName,
     * NotificationListener, NotificationFilter, Object)}, and
     * likewise for the other methods of {@link
     * NotificationBroadcaster} and {@link NotificationEmitter}.</p>
     *
     * @param connection the MBean server to forward to.
     * @param objectName the name of the MBean within
     * {@code connection} to forward to.
     * @param interfaceClass the MXBean interface,
     * which will also be implemented by the returned proxy.
     * @param notificationEmitter make the returned proxy
     * implement {@link NotificationEmitter} by forwarding its methods
     * via {@code connection}.
     *
     * @param <T> allows the compiler to know that if the {@code
     * interfaceClass} parameter is {@code MyMXBean.class}, for
     * example, then the return type is {@code MyMXBean}.
     *
     * @return the new proxy instance.
     */
    public static <T> T newMXBeanProxy(MBeanServerConnection connection,
                                       ObjectName objectName,
                                       Class<T> interfaceClass,
                                       boolean notificationEmitter) {
        // Check interface for MXBean compliance
        //
        try {
            Introspector.testComplianceMXBeanInterface(interfaceClass);
        } catch (NotCompliantMBeanException e) {
            throw new IllegalArgumentException(e);
        }
        InvocationHandler handler = new MBeanServerInvocationHandler(
                connection, objectName, true);
        final Class<?>[] interfaces;
        if (notificationEmitter) {
            interfaces =
                new Class<?>[] {interfaceClass, NotificationEmitter.class};
        } else
            interfaces = new Class<?>[] {interfaceClass};
        Object proxy = Proxy.newProxyInstance(
                interfaceClass.getClassLoader(),
                interfaces,
                handler);
        return interfaceClass.cast(proxy);
    }

    /**
     * <p>Test whether an interface is an MXBean interface.
     * An interface is an MXBean interface if it is annotated
     * {@link MXBean &#64;MXBean} or {@code @MXBean(true)}
     * or if it does not have an {@code @MXBean} annotation
     * and its name ends with "{@code MXBean}".</p>
     *
     * @param interfaceClass The candidate interface.
     *
     * @return true if {@code interfaceClass} is an interface and
     * meets the conditions described.
     *
     * @throws NullPointerException if {@code interfaceClass} is null.
     */
    public static boolean isMXBeanInterface(Class<?> interfaceClass) {
        if (!interfaceClass.isInterface())
            return false;
        MXBean a = interfaceClass.getAnnotation(MXBean.class);
        if (a != null)
            return a.value();
        return interfaceClass.getName().endsWith("MXBean");
        // We don't bother excluding the case where the name is
        // exactly the string "MXBean" since that would mean there
        // was no package name, which is pretty unlikely in practice.
    }
}
