jdk/src/java.management/share/classes/sun/management/MappedMXBeanType.java
changeset 30355 e37c7eba132f
parent 27957 24b4e6082f19
child 30655 d83f50188ca9
equal deleted inserted replaced
30354:ca83b4cae363 30355:e37c7eba132f
     1 /*
     1 /*
     2  * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    36 import java.io.InvalidObjectException;
    36 import java.io.InvalidObjectException;
    37 import java.security.AccessController;
    37 import java.security.AccessController;
    38 import java.security.PrivilegedAction;
    38 import java.security.PrivilegedAction;
    39 import java.security.PrivilegedActionException;
    39 import java.security.PrivilegedActionException;
    40 import java.security.PrivilegedExceptionAction;
    40 import java.security.PrivilegedExceptionAction;
    41 import javax.management.*;
       
    42 import javax.management.openmbean.*;
    41 import javax.management.openmbean.*;
    43 import static javax.management.openmbean.SimpleType.*;
    42 import static javax.management.openmbean.SimpleType.*;
    44 import com.sun.management.VMOption;
       
    45 
    43 
    46 /**
    44 /**
    47  * A mapped mxbean type maps a Java type to an open type.
    45  * A mapped mxbean type maps a Java type to an open type.
    48  * Only the following Java types are mappable
    46  * Only the following Java types are mappable
    49  * (currently required by the platform MXBeans):
    47  * (currently required by the platform MXBeans):
   111         MappedMXBeanType mt = new BasicMXBeanType(c, ot);
   109         MappedMXBeanType mt = new BasicMXBeanType(c, ot);
   112         convertedTypes.put(c, mt);
   110         convertedTypes.put(c, mt);
   113         return mt;
   111         return mt;
   114     }
   112     }
   115 
   113 
   116     static synchronized MappedMXBeanType getMappedType(Type t)
   114     public static synchronized MappedMXBeanType getMappedType(Type t)
   117             throws OpenDataException {
   115             throws OpenDataException {
   118         MappedMXBeanType mt = convertedTypes.get(t);
   116         MappedMXBeanType mt = convertedTypes.get(t);
   119         if (mt == null) {
   117         if (mt == null) {
   120             mt = newMappedType(t);
   118             mt = newMappedType(t);
   121         }
   119         }
   150         MappedMXBeanType mt = getMappedType(t);
   148         MappedMXBeanType mt = getMappedType(t);
   151         return mt.toOpenTypeData(data);
   149         return mt.toOpenTypeData(data);
   152     }
   150     }
   153 
   151 
   154     // Return the mapped open type
   152     // Return the mapped open type
   155     OpenType<?> getOpenType() {
   153     public OpenType<?> getOpenType() {
   156         return openType;
   154         return openType;
   157     }
   155     }
   158 
   156 
   159     boolean isBasicType() {
   157     boolean isBasicType() {
   160         return isBasicType;
   158         return isBasicType;
   175     abstract Type getJavaType();
   173     abstract Type getJavaType();
   176 
   174 
   177     // return name of the class or the generic type
   175     // return name of the class or the generic type
   178     abstract String getName();
   176     abstract String getName();
   179 
   177 
   180     abstract Object toOpenTypeData(Object javaTypeData)
   178     public abstract Object toOpenTypeData(Object javaTypeData)
   181         throws OpenDataException;
   179         throws OpenDataException;
   182 
   180 
   183     abstract Object toJavaTypeData(Object openTypeData)
   181     public abstract Object toJavaTypeData(Object openTypeData)
   184         throws OpenDataException, InvalidObjectException;
   182         throws OpenDataException, InvalidObjectException;
   185 
   183 
   186     // Basic Types - Classes that do not require data conversion
   184     // Basic Types - Classes that do not require data conversion
   187     //               including primitive types and all SimpleType
   185     //               including primitive types and all SimpleType
   188     //
   186     //
   206 
   204 
   207         String getName() {
   205         String getName() {
   208             return basicType.getName();
   206             return basicType.getName();
   209         }
   207         }
   210 
   208 
   211         Object toOpenTypeData(Object data) throws OpenDataException {
   209         public Object toOpenTypeData(Object data) throws OpenDataException {
   212             return data;
   210             return data;
   213         }
   211         }
   214 
   212 
   215         Object toJavaTypeData(Object data)
   213         public Object toJavaTypeData(Object data)
   216             throws OpenDataException, InvalidObjectException {
   214             throws OpenDataException, InvalidObjectException {
   217 
   215 
   218             return data;
   216             return data;
   219         }
   217         }
   220     }
   218     }
   241 
   239 
   242         String getName() {
   240         String getName() {
   243             return enumClass.getName();
   241             return enumClass.getName();
   244         }
   242         }
   245 
   243 
   246         Object toOpenTypeData(Object data) throws OpenDataException {
   244         public Object toOpenTypeData(Object data) throws OpenDataException {
   247             return ((Enum) data).name();
   245             return ((Enum) data).name();
   248         }
   246         }
   249 
   247 
   250         Object toJavaTypeData(Object data)
   248         public Object toJavaTypeData(Object data)
   251             throws OpenDataException, InvalidObjectException {
   249             throws OpenDataException, InvalidObjectException {
   252 
   250 
   253             try {
   251             try {
   254                 return Enum.valueOf(enumClass, (String) data);
   252                 return Enum.valueOf(enumClass, (String) data);
   255             } catch (IllegalArgumentException e) {
   253             } catch (IllegalArgumentException e) {
   313 
   311 
   314         String getName() {
   312         String getName() {
   315             return arrayClass.getName();
   313             return arrayClass.getName();
   316         }
   314         }
   317 
   315 
   318         Object toOpenTypeData(Object data) throws OpenDataException {
   316         public Object toOpenTypeData(Object data) throws OpenDataException {
   319             // If the base element type is a basic type
   317             // If the base element type is a basic type
   320             // return the data as no conversion is needed.
   318             // return the data as no conversion is needed.
   321             // Primitive types are not converted to wrappers.
   319             // Primitive types are not converted to wrappers.
   322             if (baseElementType.isBasicType()) {
   320             if (baseElementType.isBasicType()) {
   323                 return data;
   321                 return data;
   338             }
   336             }
   339             return openArray;
   337             return openArray;
   340         }
   338         }
   341 
   339 
   342 
   340 
   343         Object toJavaTypeData(Object data)
   341         public Object toJavaTypeData(Object data)
   344             throws OpenDataException, InvalidObjectException {
   342             throws OpenDataException, InvalidObjectException {
   345 
   343 
   346             // If the base element type is a basic type
   344             // If the base element type is a basic type
   347             // return the data as no conversion is needed.
   345             // return the data as no conversion is needed.
   348             if (baseElementType.isBasicType()) {
   346             if (baseElementType.isBasicType()) {
   455 
   453 
   456         String getName() {
   454         String getName() {
   457             return typeName;
   455             return typeName;
   458         }
   456         }
   459 
   457 
   460         Object toOpenTypeData(Object data) throws OpenDataException {
   458         public Object toOpenTypeData(Object data) throws OpenDataException {
   461             final List<Object> list = (List<Object>) data;
   459             final List<Object> list = (List<Object>) data;
   462 
   460 
   463             final Object[] openArray = (Object[])
   461             final Object[] openArray = (Object[])
   464                 Array.newInstance(paramType.getMappedTypeClass(),
   462                 Array.newInstance(paramType.getMappedTypeClass(),
   465                                   list.size());
   463                                   list.size());
   468                 openArray[i++] = paramType.toOpenTypeData(o);
   466                 openArray[i++] = paramType.toOpenTypeData(o);
   469             }
   467             }
   470             return openArray;
   468             return openArray;
   471         }
   469         }
   472 
   470 
   473         Object toJavaTypeData(Object data)
   471         public Object toJavaTypeData(Object data)
   474             throws OpenDataException, InvalidObjectException {
   472             throws OpenDataException, InvalidObjectException {
   475 
   473 
   476             final Object[] openArray = (Object[]) data;
   474             final Object[] openArray = (Object[]) data;
   477             List<Object> result = new ArrayList<>(openArray.length);
   475             List<Object> result = new ArrayList<>(openArray.length);
   478             for (Object o : openArray) {
   476             for (Object o : openArray) {
   536 
   534 
   537         String getName() {
   535         String getName() {
   538             return typeName;
   536             return typeName;
   539         }
   537         }
   540 
   538 
   541         Object toOpenTypeData(Object data) throws OpenDataException {
   539         public Object toOpenTypeData(Object data) throws OpenDataException {
   542             final Map<Object,Object> map = (Map<Object,Object>) data;
   540             final Map<Object,Object> map = (Map<Object,Object>) data;
   543             final TabularType tabularType = (TabularType) openType;
   541             final TabularType tabularType = (TabularType) openType;
   544             final TabularData table = new TabularDataSupport(tabularType);
   542             final TabularData table = new TabularDataSupport(tabularType);
   545             final CompositeType rowType = tabularType.getRowType();
   543             final CompositeType rowType = tabularType.getRowType();
   546 
   544 
   554                 table.put(row);
   552                 table.put(row);
   555             }
   553             }
   556             return table;
   554             return table;
   557         }
   555         }
   558 
   556 
   559         Object toJavaTypeData(Object data)
   557         public Object toJavaTypeData(Object data)
   560             throws OpenDataException, InvalidObjectException {
   558             throws OpenDataException, InvalidObjectException {
   561 
   559 
   562             final TabularData td = (TabularData) data;
   560             final TabularData td = (TabularData) data;
   563 
   561 
   564             Map<Object, Object> result = new HashMap<>();
   562             Map<Object, Object> result = new HashMap<>();
   603     // o If FooType is an array, the item type is an array and
   601     // o If FooType is an array, the item type is an array and
   604     //   its element type is determined as described above.
   602     //   its element type is determined as described above.
   605     //
   603     //
   606     static class CompositeDataMXBeanType extends MappedMXBeanType {
   604     static class CompositeDataMXBeanType extends MappedMXBeanType {
   607         final Class<?> javaClass;
   605         final Class<?> javaClass;
   608         final boolean isCompositeData;
   606         boolean isCompositeData = false;
   609         Method fromMethod = null;
   607         Method fromMethod = null;
       
   608         Method toMethod = null;
   610 
   609 
   611         CompositeDataMXBeanType(Class<?> c) throws OpenDataException {
   610         CompositeDataMXBeanType(Class<?> c) throws OpenDataException {
   612             this.javaClass = c;
   611             this.javaClass = c;
   613             this.mappedTypeClass = COMPOSITE_DATA_CLASS;
   612             this.mappedTypeClass = COMPOSITE_DATA_CLASS;
   614 
   613 
   622             } catch (PrivilegedActionException e) {
   621             } catch (PrivilegedActionException e) {
   623                 // ignore NoSuchMethodException since we allow classes
   622                 // ignore NoSuchMethodException since we allow classes
   624                 // that has no from method to be embeded in another class.
   623                 // that has no from method to be embeded in another class.
   625             }
   624             }
   626 
   625 
       
   626             // check if a static "toCompositeData" method exists
       
   627             try {
       
   628                 toMethod = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
       
   629                     public Method run() throws NoSuchMethodException {
       
   630                         Method m = javaClass.getDeclaredMethod("toCompositeData", javaClass);
       
   631                         if (m != null
       
   632                                 && CompositeData.class.isAssignableFrom(m.getReturnType())
       
   633                                 && Modifier.isStatic(m.getModifiers())) {
       
   634                             m.setAccessible(true);
       
   635                             return m;
       
   636                         } else {
       
   637                             return null;
       
   638                         }
       
   639                     }
       
   640                 });
       
   641             } catch (PrivilegedActionException e) {
       
   642                 // ignore NoSuchMethodException since we allow classes
       
   643                 // that has no from method to be embeded in another class.
       
   644             }
       
   645 
   627             if (COMPOSITE_DATA_CLASS.isAssignableFrom(c)) {
   646             if (COMPOSITE_DATA_CLASS.isAssignableFrom(c)) {
   628                 // c implements CompositeData - set openType to null
   647                 // c implements CompositeData - set openType to null
   629                 // defer generating the CompositeType
   648                 // defer generating the CompositeType
   630                 // until the object is constructed
   649                 // until the object is constructed
   631                 this.isCompositeData = true;
   650                 this.isCompositeData = true;
   634                 this.isCompositeData = false;
   653                 this.isCompositeData = false;
   635 
   654 
   636                 // Make a CompositeData containing all the getters
   655                 // Make a CompositeData containing all the getters
   637                 final Method[] methods =
   656                 final Method[] methods =
   638                     AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
   657                     AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
   639                         public Method[] run() {
   658                             public Method[] run() {
   640                             return javaClass.getMethods();
   659                                 return javaClass.getMethods();
   641                         }
   660                             }
   642                     });
   661                         });
   643                 final List<String> names = new ArrayList<>();
   662                 final List<String> names = new ArrayList<>();
   644                 final List<OpenType<?>> types = new ArrayList<>();
   663                 final List<OpenType<?>> types = new ArrayList<>();
   645 
   664 
   646                 /* Select public methods that look like "T getX()" or "boolean
   665                 /* Select public methods that look like "T getX()" or "boolean
   647                    isX()", where T is not void and X is not the empty
   666                  isX()", where T is not void and X is not the empty
   648                    string.  Exclude "Class getClass()" inherited from Object.  */
   667                  string.  Exclude "Class getClass()" inherited from Object.  */
   649                 for (int i = 0; i < methods.length; i++) {
   668                 for (int i = 0; i < methods.length; i++) {
   650                     final Method method = methods[i];
   669                     final Method method = methods[i];
   651                     final String name = method.getName();
   670                     final String name = method.getName();
   652                     final Type type = method.getGenericReturnType();
   671                     final Type type = method.getGenericReturnType();
   653                     final String rest;
   672                     final String rest;
   674                     types.add(toOpenType(type));
   693                     types.add(toOpenType(type));
   675                 }
   694                 }
   676 
   695 
   677                 final String[] nameArray = names.toArray(new String[0]);
   696                 final String[] nameArray = names.toArray(new String[0]);
   678                 openType = new CompositeType(c.getName(),
   697                 openType = new CompositeType(c.getName(),
   679                                              c.getName(),
   698                         c.getName(),
   680                                              nameArray, // field names
   699                         nameArray, // field names
   681                                              nameArray, // field descriptions
   700                         nameArray, // field descriptions
   682                                              types.toArray(new OpenType<?>[0]));
   701                         types.toArray(new OpenType<?>[0]));
   683             }
   702             }
   684         }
   703         }
   685 
   704 
   686         Type getJavaType() {
   705         Type getJavaType() {
   687             return javaClass;
   706             return javaClass;
   689 
   708 
   690         String getName() {
   709         String getName() {
   691             return javaClass.getName();
   710             return javaClass.getName();
   692         }
   711         }
   693 
   712 
   694         Object toOpenTypeData(Object data) throws OpenDataException {
   713         public Object toOpenTypeData(Object data) throws OpenDataException {
       
   714             if (toMethod != null) {
       
   715                 try {
       
   716                     return toMethod.invoke(null, data);
       
   717                 } catch (IllegalAccessException e) {
       
   718                     // should never reach here
       
   719                     throw new AssertionError(e);
       
   720                 } catch (InvocationTargetException e) {
       
   721                     final OpenDataException ode
       
   722                             = new OpenDataException("Failed to invoke "
       
   723                                     + toMethod.getName() + " to convert " + javaClass.getName()
       
   724                                     + " to CompositeData");
       
   725                     ode.initCause(e);
       
   726                     throw ode;
       
   727                 }
       
   728             }
       
   729 
   695             if (data instanceof MemoryUsage) {
   730             if (data instanceof MemoryUsage) {
   696                 return MemoryUsageCompositeData.toCompositeData((MemoryUsage) data);
   731                 return MemoryUsageCompositeData.toCompositeData((MemoryUsage) data);
   697             }
   732             }
   698 
   733 
   699             if (data instanceof ThreadInfo) {
   734             if (data instanceof ThreadInfo) {
   708             }
   743             }
   709 
   744 
   710             if (data instanceof MemoryNotificationInfo) {
   745             if (data instanceof MemoryNotificationInfo) {
   711                 return MemoryNotifInfoCompositeData.
   746                 return MemoryNotifInfoCompositeData.
   712                     toCompositeData((MemoryNotificationInfo) data);
   747                     toCompositeData((MemoryNotificationInfo) data);
   713             }
       
   714 
       
   715             if (data instanceof VMOption) {
       
   716                 return VMOptionCompositeData.toCompositeData((VMOption) data);
       
   717             }
   748             }
   718 
   749 
   719             if (isCompositeData) {
   750             if (isCompositeData) {
   720                 // Classes that implement CompositeData
   751                 // Classes that implement CompositeData
   721                 //
   752                 //
   730 
   761 
   731             throw new OpenDataException(javaClass.getName() +
   762             throw new OpenDataException(javaClass.getName() +
   732                 " is not supported for platform MXBeans");
   763                 " is not supported for platform MXBeans");
   733         }
   764         }
   734 
   765 
   735         Object toJavaTypeData(Object data)
   766         public Object toJavaTypeData(Object data)
   736             throws OpenDataException, InvalidObjectException {
   767             throws OpenDataException, InvalidObjectException {
   737 
   768 
   738             if (fromMethod == null) {
   769             if (fromMethod == null) {
   739                 throw new AssertionError("Does not support data conversion");
   770                 throw new AssertionError("Does not support data conversion");
   740             }
   771             }