jdk/src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java
changeset 687 874e25a9844a
parent 2 90ce3da70b43
child 715 f16baef3a20e
equal deleted inserted replaced
686:d0c74839e1bd 687:874e25a9844a
    29 import java.lang.reflect.Method;
    29 import java.lang.reflect.Method;
    30 import java.lang.reflect.Type;
    30 import java.lang.reflect.Type;
    31 
    31 
    32 import javax.management.Descriptor;
    32 import javax.management.Descriptor;
    33 import javax.management.MBeanException;
    33 import javax.management.MBeanException;
       
    34 import javax.management.openmbean.MXBeanMapping;
       
    35 import javax.management.openmbean.MXBeanMappingFactory;
    34 import javax.management.openmbean.OpenDataException;
    36 import javax.management.openmbean.OpenDataException;
    35 import javax.management.openmbean.OpenType;
    37 import javax.management.openmbean.OpenType;
    36 
    38 
    37 final class ConvertingMethod {
    39 final class ConvertingMethod {
    38     static ConvertingMethod from(Method m) {
    40     static ConvertingMethod from(Method m, MXBeanMappingFactory mappingFactory) {
    39         try {
    41         try {
    40             return new ConvertingMethod(m);
    42             return new ConvertingMethod(m, mappingFactory);
    41         } catch (OpenDataException ode) {
    43         } catch (OpenDataException ode) {
    42             final String msg = "Method " + m.getDeclaringClass().getName() +
    44             final String msg = "Method " + m.getDeclaringClass().getName() +
    43                 "." + m.getName() + " has parameter or return type that " +
    45                 "." + m.getName() + " has parameter or return type that " +
    44                 "cannot be translated into an open type";
    46                 "cannot be translated into an open type";
    45             throw new IllegalArgumentException(msg, ode);
    47             throw new IllegalArgumentException(msg, ode);
    65     String getName() {
    67     String getName() {
    66         return method.getName();
    68         return method.getName();
    67     }
    69     }
    68 
    70 
    69     OpenType getOpenReturnType() {
    71     OpenType getOpenReturnType() {
    70         return returnConverter.getOpenType();
    72         return returnMapping.getOpenType();
    71     }
    73     }
    72 
    74 
    73     OpenType[] getOpenParameterTypes() {
    75     OpenType[] getOpenParameterTypes() {
    74         final OpenType[] types = new OpenType[paramConverters.length];
    76         final OpenType[] types = new OpenType[paramMappings.length];
    75         for (int i = 0; i < paramConverters.length; i++)
    77         for (int i = 0; i < paramMappings.length; i++)
    76             types[i] = paramConverters[i].getOpenType();
    78             types[i] = paramMappings[i].getOpenType();
    77         return types;
    79         return types;
    78     }
    80     }
    79 
    81 
    80     /* Check that this method will be callable when we are going from
    82     /* Check that this method will be callable when we are going from
    81      * open types to Java types, for example when we are going from
    83      * open types to Java types, for example when we are going from
    83      * The parameters will be converted to
    85      * The parameters will be converted to
    84      * Java types, so they must be "reconstructible".  The return
    86      * Java types, so they must be "reconstructible".  The return
    85      * value will be converted to an Open Type, so if it is convertible
    87      * value will be converted to an Open Type, so if it is convertible
    86      * at all there is no further check needed.
    88      * at all there is no further check needed.
    87      */
    89      */
    88     void checkCallFromOpen() throws IllegalArgumentException {
    90     void checkCallFromOpen() {
    89         try {
    91         try {
    90             for (OpenConverter paramConverter : paramConverters)
    92             for (MXBeanMapping paramConverter : paramMappings)
    91                 paramConverter.checkReconstructible();
    93                 paramConverter.checkReconstructible();
    92         } catch (InvalidObjectException e) {
    94         } catch (InvalidObjectException e) {
    93             throw new IllegalArgumentException(e);
    95             throw new IllegalArgumentException(e);
    94         }
    96         }
    95     }
    97     }
   100      * The return type will be converted back to a Java type, so it
   102      * The return type will be converted back to a Java type, so it
   101      * must be "reconstructible".  The parameters will be converted to
   103      * must be "reconstructible".  The parameters will be converted to
   102      * open types, so if it is convertible at all there is no further
   104      * open types, so if it is convertible at all there is no further
   103      * check needed.
   105      * check needed.
   104      */
   106      */
   105     void checkCallToOpen() throws IllegalArgumentException {
   107     void checkCallToOpen() {
   106         try {
   108         try {
   107             returnConverter.checkReconstructible();
   109             returnMapping.checkReconstructible();
   108         } catch (InvalidObjectException e) {
   110         } catch (InvalidObjectException e) {
   109             throw new IllegalArgumentException(e);
   111             throw new IllegalArgumentException(e);
   110         }
   112         }
   111     }
   113     }
   112 
   114 
   113     String[] getOpenSignature() {
   115     String[] getOpenSignature() {
   114         if (paramConverters.length == 0)
   116         if (paramMappings.length == 0)
   115             return noStrings;
   117             return noStrings;
   116 
   118 
   117         String[] sig = new String[paramConverters.length];
   119         String[] sig = new String[paramMappings.length];
   118         for (int i = 0; i < paramConverters.length; i++)
   120         for (int i = 0; i < paramMappings.length; i++)
   119             sig[i] = paramConverters[i].getOpenClass().getName();
   121             sig[i] = paramMappings[i].getOpenClass().getName();
   120         return sig;
   122         return sig;
   121     }
   123     }
   122 
   124 
   123     final Object toOpenReturnValue(MXBeanLookup lookup, Object ret)
   125     final Object toOpenReturnValue(MXBeanLookup lookup, Object ret)
   124             throws OpenDataException {
   126             throws OpenDataException {
   125         return returnConverter.toOpenValue(lookup, ret);
   127         return returnMapping.toOpenValue(ret);
   126     }
   128     }
   127 
   129 
   128     final Object fromOpenReturnValue(MXBeanLookup lookup, Object ret)
   130     final Object fromOpenReturnValue(MXBeanLookup lookup, Object ret)
   129             throws InvalidObjectException {
   131             throws InvalidObjectException {
   130         return returnConverter.fromOpenValue(lookup, ret);
   132         return returnMapping.fromOpenValue(ret);
   131     }
   133     }
   132 
   134 
   133     final Object[] toOpenParameters(MXBeanLookup lookup, Object[] params)
   135     final Object[] toOpenParameters(MXBeanLookup lookup, Object[] params)
   134             throws OpenDataException {
   136             throws OpenDataException {
   135         if (paramConversionIsIdentity || params == null)
   137         if (paramConversionIsIdentity || params == null)
   136             return params;
   138             return params;
   137         final Object[] oparams = new Object[params.length];
   139         final Object[] oparams = new Object[params.length];
   138         for (int i = 0; i < params.length; i++)
   140         for (int i = 0; i < params.length; i++)
   139             oparams[i] = paramConverters[i].toOpenValue(lookup, params[i]);
   141             oparams[i] = paramMappings[i].toOpenValue(params[i]);
   140         return oparams;
   142         return oparams;
   141     }
   143     }
   142 
   144 
   143     final Object[] fromOpenParameters(MXBeanLookup lookup, Object[] params)
   145     final Object[] fromOpenParameters(Object[] params)
   144             throws InvalidObjectException {
   146             throws InvalidObjectException {
   145         if (paramConversionIsIdentity || params == null)
   147         if (paramConversionIsIdentity || params == null)
   146             return params;
   148             return params;
   147         final Object[] jparams = new Object[params.length];
   149         final Object[] jparams = new Object[params.length];
   148         for (int i = 0; i < params.length; i++)
   150         for (int i = 0; i < params.length; i++)
   149             jparams[i] = paramConverters[i].fromOpenValue(lookup, params[i]);
   151             jparams[i] = paramMappings[i].fromOpenValue(params[i]);
   150         return jparams;
   152         return jparams;
   151     }
   153     }
   152 
   154 
   153     final Object toOpenParameter(MXBeanLookup lookup,
   155     final Object toOpenParameter(MXBeanLookup lookup,
   154                                  Object param,
   156                                  Object param,
   155                                  int paramNo)
   157                                  int paramNo)
   156         throws OpenDataException {
   158         throws OpenDataException {
   157         return paramConverters[paramNo].toOpenValue(lookup, param);
   159         return paramMappings[paramNo].toOpenValue(param);
   158     }
   160     }
   159 
   161 
   160     final Object fromOpenParameter(MXBeanLookup lookup,
   162     final Object fromOpenParameter(MXBeanLookup lookup,
   161                                    Object param,
   163                                    Object param,
   162                                    int paramNo)
   164                                    int paramNo)
   163         throws InvalidObjectException {
   165         throws InvalidObjectException {
   164         return paramConverters[paramNo].fromOpenValue(lookup, param);
   166         return paramMappings[paramNo].fromOpenValue(param);
   165     }
   167     }
   166 
   168 
   167     Object invokeWithOpenReturn(MXBeanLookup lookup,
   169     Object invokeWithOpenReturn(MXBeanLookup lookup,
   168                                 Object obj, Object[] params)
   170                                 Object obj, Object[] params)
   169             throws MBeanException, IllegalAccessException,
   171             throws MBeanException, IllegalAccessException,
   170                    InvocationTargetException {
   172                    InvocationTargetException {
       
   173         MXBeanLookup old = MXBeanLookup.getLookup();
       
   174         try {
       
   175             MXBeanLookup.setLookup(lookup);
       
   176             return invokeWithOpenReturn(obj, params);
       
   177         } finally {
       
   178             MXBeanLookup.setLookup(old);
       
   179         }
       
   180     }
       
   181 
       
   182     private Object invokeWithOpenReturn(Object obj, Object[] params)
       
   183             throws MBeanException, IllegalAccessException,
       
   184                    InvocationTargetException {
   171         final Object[] javaParams;
   185         final Object[] javaParams;
   172         try {
   186         try {
   173             javaParams = fromOpenParameters(lookup, params);
   187             javaParams = fromOpenParameters(params);
   174         } catch (InvalidObjectException e) {
   188         } catch (InvalidObjectException e) {
   175             // probably can't happen
   189             // probably can't happen
   176             final String msg = methodName() + ": cannot convert parameters " +
   190             final String msg = methodName() + ": cannot convert parameters " +
   177                 "from open values: " + e;
   191                 "from open values: " + e;
   178             throw new MBeanException(e, msg);
   192             throw new MBeanException(e, msg);
   179         }
   193         }
   180         final Object javaReturn = method.invoke(obj, javaParams);
   194         final Object javaReturn = method.invoke(obj, javaParams);
   181         try {
   195         try {
   182             return returnConverter.toOpenValue(lookup, javaReturn);
   196             return returnMapping.toOpenValue(javaReturn);
   183         } catch (OpenDataException e) {
   197         } catch (OpenDataException e) {
   184             // probably can't happen
   198             // probably can't happen
   185             final String msg = methodName() + ": cannot convert return " +
   199             final String msg = methodName() + ": cannot convert return " +
   186                 "value to open value: " + e;
   200                 "value to open value: " + e;
   187             throw new MBeanException(e, msg);
   201             throw new MBeanException(e, msg);
   190 
   204 
   191     private String methodName() {
   205     private String methodName() {
   192         return method.getDeclaringClass() + "." + method.getName();
   206         return method.getDeclaringClass() + "." + method.getName();
   193     }
   207     }
   194 
   208 
   195     private ConvertingMethod(Method m) throws OpenDataException {
   209     private ConvertingMethod(Method m, MXBeanMappingFactory mappingFactory)
       
   210     throws OpenDataException {
   196         this.method = m;
   211         this.method = m;
   197         returnConverter = OpenConverter.toConverter(m.getGenericReturnType());
   212         returnMapping =
       
   213                 mappingFactory.mappingForType(m.getGenericReturnType(), mappingFactory);
   198         Type[] params = m.getGenericParameterTypes();
   214         Type[] params = m.getGenericParameterTypes();
   199         paramConverters = new OpenConverter[params.length];
   215         paramMappings = new MXBeanMapping[params.length];
   200         boolean identity = true;
   216         boolean identity = true;
   201         for (int i = 0; i < params.length; i++) {
   217         for (int i = 0; i < params.length; i++) {
   202             paramConverters[i] = OpenConverter.toConverter(params[i]);
   218             paramMappings[i] = mappingFactory.mappingForType(params[i], mappingFactory);
   203             identity &= paramConverters[i].isIdentity();
   219             identity &= DefaultMXBeanMappingFactory.isIdentity(paramMappings[i]);
   204         }
   220         }
   205         paramConversionIsIdentity = identity;
   221         paramConversionIsIdentity = identity;
   206     }
   222     }
   207 
   223 
   208     private static final String[] noStrings = new String[0];
   224     private static final String[] noStrings = new String[0];
   209 
   225 
   210     private final Method method;
   226     private final Method method;
   211     private final OpenConverter returnConverter;
   227     private final MXBeanMapping returnMapping;
   212     private final OpenConverter[] paramConverters;
   228     private final MXBeanMapping[] paramMappings;
   213     private final boolean paramConversionIsIdentity;
   229     private final boolean paramConversionIsIdentity;
   214 }
   230 }