175 lines · 6.2 KB · Java
RawDownload
/* * Copyright (c) 2005, 2008, 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.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) {         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);        MXBeanLookup oldLookup = MXBeanLookup.getLookup();        try {            MXBeanLookup.setLookup(lookup);            Object[] openArgs = cm.toOpenParameters(lookup, args);            Object result = handler.invoke(mbsc, name, openArgs);            return cm.fromOpenReturnValue(lookup, result);        } finally {            MXBeanLookup.setLookup(oldLookup);        }    }     private final Map<Method, Handler> handlerMap = newMap();}