Path: blob/master/src/java.management/share/classes/com/sun/jmx/mbeanserver/MXBeanProxy.java
41161 views
/*1* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.jmx.mbeanserver;2627import static com.sun.jmx.mbeanserver.Util.*;2829import java.lang.reflect.Method;30import java.util.Map;3132import javax.management.Attribute;33import javax.management.MBeanServerConnection;34import javax.management.NotCompliantMBeanException;35import javax.management.ObjectName;3637/**38<p>Helper class for an {@link InvocationHandler} that forwards methods from an39MXBean interface to a named40MXBean in an MBean Server and handles translation between the41arbitrary Java types in the interface and the Open Types used42by the MXBean.</p>4344@since 1.645*/46public class MXBeanProxy {47public MXBeanProxy(Class<?> mxbeanInterface) {4849if (mxbeanInterface == null)50throw new IllegalArgumentException("Null parameter");5152final MBeanAnalyzer<ConvertingMethod> analyzer;53try {54analyzer =55MXBeanIntrospector.getInstance().getAnalyzer(mxbeanInterface);56} catch (NotCompliantMBeanException e) {57throw new IllegalArgumentException(e);58}59analyzer.visit(new Visitor());60}6162private class Visitor63implements MBeanAnalyzer.MBeanVisitor<ConvertingMethod> {64public void visitAttribute(String attributeName,65ConvertingMethod getter,66ConvertingMethod setter) {67if (getter != null) {68getter.checkCallToOpen();69Method getterMethod = getter.getMethod();70handlerMap.put(getterMethod,71new GetHandler(attributeName, getter));72}73if (setter != null) {74// return type is void, no need for checkCallToOpen75Method setterMethod = setter.getMethod();76handlerMap.put(setterMethod,77new SetHandler(attributeName, setter));78}79}8081public void visitOperation(String operationName,82ConvertingMethod operation) {83operation.checkCallToOpen();84Method operationMethod = operation.getMethod();85String[] sig = operation.getOpenSignature();86handlerMap.put(operationMethod,87new InvokeHandler(operationName, sig, operation));88}89}9091private static abstract class Handler {92Handler(String name, ConvertingMethod cm) {93this.name = name;94this.convertingMethod = cm;95}9697String getName() {98return name;99}100101ConvertingMethod getConvertingMethod() {102return convertingMethod;103}104105abstract Object invoke(MBeanServerConnection mbsc,106ObjectName name, Object[] args) throws Exception;107108private final String name;109private final ConvertingMethod convertingMethod;110}111112private static class GetHandler extends Handler {113GetHandler(String attributeName, ConvertingMethod cm) {114super(attributeName, cm);115}116117@Override118Object invoke(MBeanServerConnection mbsc, ObjectName name, Object[] args)119throws Exception {120assert(args == null || args.length == 0);121return mbsc.getAttribute(name, getName());122}123}124125private static class SetHandler extends Handler {126SetHandler(String attributeName, ConvertingMethod cm) {127super(attributeName, cm);128}129130@Override131Object invoke(MBeanServerConnection mbsc, ObjectName name, Object[] args)132throws Exception {133assert(args.length == 1);134Attribute attr = new Attribute(getName(), args[0]);135mbsc.setAttribute(name, attr);136return null;137}138}139140private static class InvokeHandler extends Handler {141InvokeHandler(String operationName, String[] signature,142ConvertingMethod cm) {143super(operationName, cm);144this.signature = signature;145}146147Object invoke(MBeanServerConnection mbsc, ObjectName name, Object[] args)148throws Exception {149return mbsc.invoke(name, getName(), args, signature);150}151152private final String[] signature;153}154155public Object invoke(MBeanServerConnection mbsc, ObjectName name,156Method method, Object[] args)157throws Throwable {158159Handler handler = handlerMap.get(method);160ConvertingMethod cm = handler.getConvertingMethod();161MXBeanLookup lookup = MXBeanLookup.lookupFor(mbsc);162MXBeanLookup oldLookup = MXBeanLookup.getLookup();163try {164MXBeanLookup.setLookup(lookup);165Object[] openArgs = cm.toOpenParameters(lookup, args);166Object result = handler.invoke(mbsc, name, openArgs);167return cm.fromOpenReturnValue(lookup, result);168} finally {169MXBeanLookup.setLookup(oldLookup);170}171}172173private final Map<Method, Handler> handlerMap = newMap();174}175176177