Path: blob/master/src/java.management/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java
41171 views
/*1* Copyright (c) 2005, 2013, 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;26import java.io.InvalidObjectException;27import java.lang.reflect.InvocationTargetException;28import java.lang.reflect.Method;29import java.lang.reflect.Type;3031import javax.management.Descriptor;32import javax.management.MBeanException;33import javax.management.openmbean.OpenDataException;34import javax.management.openmbean.OpenType;35import sun.reflect.misc.MethodUtil;3637final class ConvertingMethod {38static ConvertingMethod from(Method m) {39try {40return new ConvertingMethod(m);41} catch (OpenDataException ode) {42final String msg = "Method " + m.getDeclaringClass().getName() +43"." + m.getName() + " has parameter or return type that " +44"cannot be translated into an open type";45throw new IllegalArgumentException(msg, ode);46}47}4849Method getMethod() {50return method;51}5253Descriptor getDescriptor() {54return Introspector.descriptorForElement(method);55}5657Type getGenericReturnType() {58return method.getGenericReturnType();59}6061Type[] getGenericParameterTypes() {62return method.getGenericParameterTypes();63}6465String getName() {66return method.getName();67}6869OpenType<?> getOpenReturnType() {70return returnMapping.getOpenType();71}7273OpenType<?>[] getOpenParameterTypes() {74final OpenType<?>[] types = new OpenType<?>[paramMappings.length];75for (int i = 0; i < paramMappings.length; i++)76types[i] = paramMappings[i].getOpenType();77return types;78}7980/* Check that this method will be callable when we are going from81* open types to Java types, for example when we are going from82* an MXBean wrapper to the underlying resource.83* The parameters will be converted to84* Java types, so they must be "reconstructible". The return85* value will be converted to an Open Type, so if it is convertible86* at all there is no further check needed.87*/88void checkCallFromOpen() {89try {90for (MXBeanMapping paramConverter : paramMappings)91paramConverter.checkReconstructible();92} catch (InvalidObjectException e) {93throw new IllegalArgumentException(e);94}95}9697/* Check that this method will be callable when we are going from98* Java types to open types, for example when we are going from99* an MXBean proxy to the open types that it will be mapped to.100* The return type will be converted back to a Java type, so it101* must be "reconstructible". The parameters will be converted to102* open types, so if it is convertible at all there is no further103* check needed.104*/105void checkCallToOpen() {106try {107returnMapping.checkReconstructible();108} catch (InvalidObjectException e) {109throw new IllegalArgumentException(e);110}111}112113String[] getOpenSignature() {114if (paramMappings.length == 0)115return noStrings;116117String[] sig = new String[paramMappings.length];118for (int i = 0; i < paramMappings.length; i++)119sig[i] = paramMappings[i].getOpenClass().getName();120return sig;121}122123final Object toOpenReturnValue(MXBeanLookup lookup, Object ret)124throws OpenDataException {125return returnMapping.toOpenValue(ret);126}127128final Object fromOpenReturnValue(MXBeanLookup lookup, Object ret)129throws InvalidObjectException {130return returnMapping.fromOpenValue(ret);131}132133final Object[] toOpenParameters(MXBeanLookup lookup, Object[] params)134throws OpenDataException {135if (paramConversionIsIdentity || params == null)136return params;137final Object[] oparams = new Object[params.length];138for (int i = 0; i < params.length; i++)139oparams[i] = paramMappings[i].toOpenValue(params[i]);140return oparams;141}142143final Object[] fromOpenParameters(Object[] params)144throws InvalidObjectException {145if (paramConversionIsIdentity || params == null)146return params;147final Object[] jparams = new Object[params.length];148for (int i = 0; i < params.length; i++)149jparams[i] = paramMappings[i].fromOpenValue(params[i]);150return jparams;151}152153final Object toOpenParameter(MXBeanLookup lookup,154Object param,155int paramNo)156throws OpenDataException {157return paramMappings[paramNo].toOpenValue(param);158}159160final Object fromOpenParameter(MXBeanLookup lookup,161Object param,162int paramNo)163throws InvalidObjectException {164return paramMappings[paramNo].fromOpenValue(param);165}166167Object invokeWithOpenReturn(MXBeanLookup lookup,168Object obj, Object[] params)169throws MBeanException, IllegalAccessException,170InvocationTargetException {171MXBeanLookup old = MXBeanLookup.getLookup();172try {173MXBeanLookup.setLookup(lookup);174return invokeWithOpenReturn(obj, params);175} finally {176MXBeanLookup.setLookup(old);177}178}179180private Object invokeWithOpenReturn(Object obj, Object[] params)181throws MBeanException, IllegalAccessException,182InvocationTargetException {183final Object[] javaParams;184try {185javaParams = fromOpenParameters(params);186} catch (InvalidObjectException e) {187// probably can't happen188final String msg = methodName() + ": cannot convert parameters " +189"from open values: " + e;190throw new MBeanException(e, msg);191}192final Object javaReturn = MethodUtil.invoke(method, obj, javaParams);193try {194return returnMapping.toOpenValue(javaReturn);195} catch (OpenDataException e) {196// probably can't happen197final String msg = methodName() + ": cannot convert return " +198"value to open value: " + e;199throw new MBeanException(e, msg);200}201}202203private String methodName() {204return method.getDeclaringClass() + "." + method.getName();205}206207private ConvertingMethod(Method m) throws OpenDataException {208this.method = m;209MXBeanMappingFactory mappingFactory = MXBeanMappingFactory.DEFAULT;210returnMapping =211mappingFactory.mappingForType(m.getGenericReturnType(), mappingFactory);212Type[] params = m.getGenericParameterTypes();213paramMappings = new MXBeanMapping[params.length];214boolean identity = true;215for (int i = 0; i < params.length; i++) {216paramMappings[i] = mappingFactory.mappingForType(params[i], mappingFactory);217identity &= DefaultMXBeanMappingFactory.isIdentity(paramMappings[i]);218}219paramConversionIsIdentity = identity;220}221222private static final String[] noStrings = new String[0];223224private final Method method;225private final MXBeanMapping returnMapping;226private final MXBeanMapping[] paramMappings;227private final boolean paramConversionIsIdentity;228}229230231