0N/A/*
2362N/A * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage com.sun.jmx.mbeanserver;
0N/Aimport java.io.InvalidObjectException;
0N/Aimport java.lang.reflect.InvocationTargetException;
0N/Aimport java.lang.reflect.Method;
0N/Aimport java.lang.reflect.Type;
0N/A
0N/Aimport javax.management.Descriptor;
0N/Aimport javax.management.MBeanException;
0N/Aimport javax.management.openmbean.OpenDataException;
0N/Aimport javax.management.openmbean.OpenType;
6287N/Aimport sun.reflect.misc.MethodUtil;
0N/A
0N/Afinal class ConvertingMethod {
1790N/A static ConvertingMethod from(Method m) {
0N/A try {
1790N/A return new ConvertingMethod(m);
0N/A } catch (OpenDataException ode) {
0N/A final String msg = "Method " + m.getDeclaringClass().getName() +
0N/A "." + m.getName() + " has parameter or return type that " +
0N/A "cannot be translated into an open type";
0N/A throw new IllegalArgumentException(msg, ode);
0N/A }
0N/A }
0N/A
0N/A Method getMethod() {
0N/A return method;
0N/A }
0N/A
0N/A Descriptor getDescriptor() {
1790N/A return Introspector.descriptorForElement(method);
0N/A }
0N/A
0N/A Type getGenericReturnType() {
0N/A return method.getGenericReturnType();
0N/A }
0N/A
0N/A Type[] getGenericParameterTypes() {
0N/A return method.getGenericParameterTypes();
0N/A }
0N/A
0N/A String getName() {
0N/A return method.getName();
0N/A }
0N/A
686N/A OpenType<?> getOpenReturnType() {
353N/A return returnMapping.getOpenType();
0N/A }
0N/A
686N/A OpenType<?>[] getOpenParameterTypes() {
686N/A final OpenType<?>[] types = new OpenType<?>[paramMappings.length];
353N/A for (int i = 0; i < paramMappings.length; i++)
353N/A types[i] = paramMappings[i].getOpenType();
0N/A return types;
0N/A }
0N/A
0N/A /* Check that this method will be callable when we are going from
0N/A * open types to Java types, for example when we are going from
0N/A * an MXBean wrapper to the underlying resource.
0N/A * The parameters will be converted to
0N/A * Java types, so they must be "reconstructible". The return
0N/A * value will be converted to an Open Type, so if it is convertible
0N/A * at all there is no further check needed.
0N/A */
353N/A void checkCallFromOpen() {
0N/A try {
353N/A for (MXBeanMapping paramConverter : paramMappings)
0N/A paramConverter.checkReconstructible();
0N/A } catch (InvalidObjectException e) {
0N/A throw new IllegalArgumentException(e);
0N/A }
0N/A }
0N/A
0N/A /* Check that this method will be callable when we are going from
0N/A * Java types to open types, for example when we are going from
0N/A * an MXBean proxy to the open types that it will be mapped to.
0N/A * The return type will be converted back to a Java type, so it
0N/A * must be "reconstructible". The parameters will be converted to
0N/A * open types, so if it is convertible at all there is no further
0N/A * check needed.
0N/A */
353N/A void checkCallToOpen() {
0N/A try {
353N/A returnMapping.checkReconstructible();
0N/A } catch (InvalidObjectException e) {
0N/A throw new IllegalArgumentException(e);
0N/A }
0N/A }
0N/A
0N/A String[] getOpenSignature() {
353N/A if (paramMappings.length == 0)
0N/A return noStrings;
0N/A
353N/A String[] sig = new String[paramMappings.length];
353N/A for (int i = 0; i < paramMappings.length; i++)
353N/A sig[i] = paramMappings[i].getOpenClass().getName();
0N/A return sig;
0N/A }
0N/A
0N/A final Object toOpenReturnValue(MXBeanLookup lookup, Object ret)
0N/A throws OpenDataException {
353N/A return returnMapping.toOpenValue(ret);
0N/A }
0N/A
0N/A final Object fromOpenReturnValue(MXBeanLookup lookup, Object ret)
0N/A throws InvalidObjectException {
353N/A return returnMapping.fromOpenValue(ret);
0N/A }
0N/A
0N/A final Object[] toOpenParameters(MXBeanLookup lookup, Object[] params)
0N/A throws OpenDataException {
0N/A if (paramConversionIsIdentity || params == null)
0N/A return params;
0N/A final Object[] oparams = new Object[params.length];
0N/A for (int i = 0; i < params.length; i++)
353N/A oparams[i] = paramMappings[i].toOpenValue(params[i]);
0N/A return oparams;
0N/A }
0N/A
353N/A final Object[] fromOpenParameters(Object[] params)
0N/A throws InvalidObjectException {
0N/A if (paramConversionIsIdentity || params == null)
0N/A return params;
0N/A final Object[] jparams = new Object[params.length];
0N/A for (int i = 0; i < params.length; i++)
353N/A jparams[i] = paramMappings[i].fromOpenValue(params[i]);
0N/A return jparams;
0N/A }
0N/A
0N/A final Object toOpenParameter(MXBeanLookup lookup,
0N/A Object param,
0N/A int paramNo)
0N/A throws OpenDataException {
353N/A return paramMappings[paramNo].toOpenValue(param);
0N/A }
0N/A
0N/A final Object fromOpenParameter(MXBeanLookup lookup,
0N/A Object param,
0N/A int paramNo)
0N/A throws InvalidObjectException {
353N/A return paramMappings[paramNo].fromOpenValue(param);
0N/A }
0N/A
0N/A Object invokeWithOpenReturn(MXBeanLookup lookup,
0N/A Object obj, Object[] params)
0N/A throws MBeanException, IllegalAccessException,
0N/A InvocationTargetException {
353N/A MXBeanLookup old = MXBeanLookup.getLookup();
353N/A try {
353N/A MXBeanLookup.setLookup(lookup);
353N/A return invokeWithOpenReturn(obj, params);
353N/A } finally {
353N/A MXBeanLookup.setLookup(old);
353N/A }
353N/A }
353N/A
353N/A private Object invokeWithOpenReturn(Object obj, Object[] params)
353N/A throws MBeanException, IllegalAccessException,
353N/A InvocationTargetException {
0N/A final Object[] javaParams;
0N/A try {
353N/A javaParams = fromOpenParameters(params);
0N/A } catch (InvalidObjectException e) {
0N/A // probably can't happen
0N/A final String msg = methodName() + ": cannot convert parameters " +
0N/A "from open values: " + e;
0N/A throw new MBeanException(e, msg);
0N/A }
6287N/A final Object javaReturn = MethodUtil.invoke(method, obj, javaParams);
0N/A try {
353N/A return returnMapping.toOpenValue(javaReturn);
0N/A } catch (OpenDataException e) {
0N/A // probably can't happen
0N/A final String msg = methodName() + ": cannot convert return " +
0N/A "value to open value: " + e;
0N/A throw new MBeanException(e, msg);
0N/A }
0N/A }
0N/A
0N/A private String methodName() {
0N/A return method.getDeclaringClass() + "." + method.getName();
0N/A }
0N/A
1790N/A private ConvertingMethod(Method m) throws OpenDataException {
0N/A this.method = m;
1790N/A MXBeanMappingFactory mappingFactory = MXBeanMappingFactory.DEFAULT;
353N/A returnMapping =
353N/A mappingFactory.mappingForType(m.getGenericReturnType(), mappingFactory);
0N/A Type[] params = m.getGenericParameterTypes();
353N/A paramMappings = new MXBeanMapping[params.length];
0N/A boolean identity = true;
0N/A for (int i = 0; i < params.length; i++) {
353N/A paramMappings[i] = mappingFactory.mappingForType(params[i], mappingFactory);
353N/A identity &= DefaultMXBeanMappingFactory.isIdentity(paramMappings[i]);
0N/A }
0N/A paramConversionIsIdentity = identity;
0N/A }
0N/A
0N/A private static final String[] noStrings = new String[0];
0N/A
0N/A private final Method method;
353N/A private final MXBeanMapping returnMapping;
353N/A private final MXBeanMapping[] paramMappings;
0N/A private final boolean paramConversionIsIdentity;
0N/A}