/* * 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 com.sun.jmx.mbeanserver; import static com.sun.jmx.mbeanserver.Util.*; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Map; import javax.management.Attribute; import javax.management.MBeanServerConnection; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; /** <p>Helper class for an {@link InvocationHandler} that forwards methods from an MXBean interface to a named MXBean in an MBean Server and handles translation between the arbitrary Java types in the interface and the Open Types used by the MXBean.</p> @since 1.6 */ public class MXBeanProxy { public MXBeanProxy(Class<?> mxbeanInterface) throws IllegalArgumentException { if (mxbeanInterface == null) throw new IllegalArgumentException("Null parameter"); final MBeanAnalyzer<ConvertingMethod> analyzer; try { analyzer = MXBeanIntrospector.getInstance().getAnalyzer(mxbeanInterface); } catch (NotCompliantMBeanException e) { throw new IllegalArgumentException(e); } analyzer.visit(new Visitor()); } private class Visitor implements MBeanAnalyzer.MBeanVisitor<ConvertingMethod> { public void visitAttribute(String attributeName, ConvertingMethod getter, ConvertingMethod setter) { if (getter != null) { getter.checkCallToOpen(); Method getterMethod = getter.getMethod(); handlerMap.put(getterMethod, new GetHandler(attributeName, getter)); } if (setter != null) { // return type is void, no need for checkCallToOpen Method setterMethod = setter.getMethod(); handlerMap.put(setterMethod, new SetHandler(attributeName, setter)); } } public void visitOperation(String operationName, ConvertingMethod operation) { operation.checkCallToOpen(); Method operationMethod = operation.getMethod(); String[] sig = operation.getOpenSignature(); handlerMap.put(operationMethod, new InvokeHandler(operationName, sig, operation)); } } private static abstract class Handler { Handler(String name, ConvertingMethod cm) { this.name = name; this.convertingMethod = cm; } String getName() { return name; } ConvertingMethod getConvertingMethod() { return convertingMethod; } abstract Object invoke(MBeanServerConnection mbsc, ObjectName name, Object[] args) throws Exception; private final String name; private final ConvertingMethod convertingMethod; } private static class GetHandler extends Handler { GetHandler(String attributeName, ConvertingMethod cm) { super(attributeName, cm); } @Override Object invoke(MBeanServerConnection mbsc, ObjectName name, Object[] args) throws Exception { assert(args == null || args.length == 0); return mbsc.getAttribute(name, getName()); } } private static class SetHandler extends Handler { SetHandler(String attributeName, ConvertingMethod cm) { super(attributeName, cm); } @Override Object invoke(MBeanServerConnection mbsc, ObjectName name, Object[] args) throws Exception { assert(args.length == 1); Attribute attr = new Attribute(getName(), args[0]); mbsc.setAttribute(name, attr); return null; } } private static class InvokeHandler extends Handler { InvokeHandler(String operationName, String[] signature, ConvertingMethod cm) { super(operationName, cm); this.signature = signature; } Object invoke(MBeanServerConnection mbsc, ObjectName name, Object[] args) throws Exception { return mbsc.invoke(name, getName(), args, signature); } private final String[] signature; } public Object invoke(MBeanServerConnection mbsc, ObjectName name, Method method, Object[] args) throws Throwable { Handler handler = handlerMap.get(method); ConvertingMethod cm = handler.getConvertingMethod(); MXBeanLookup lookup = MXBeanLookup.lookupFor(mbsc); Object[] openArgs = cm.toOpenParameters(lookup, args); Object result = handler.invoke(mbsc, name, openArgs); return cm.fromOpenReturnValue(lookup, result); } private final Map<Method, Handler> handlerMap = newMap(); }