< prev index next >

jdk/src/java.management/share/classes/sun/management/MappedMXBeanType.java

Print this page


   1 /*
   2  * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.management;
  27 import java.lang.management.MemoryUsage;
  28 import java.lang.management.MemoryNotificationInfo;
  29 import java.lang.management.MonitorInfo;
  30 import java.lang.management.LockInfo;
  31 import java.lang.management.ThreadInfo;
  32 import java.lang.reflect.*;
  33 import java.util.List;
  34 import java.util.Map;
  35 import java.util.*;
  36 import java.io.InvalidObjectException;
  37 import java.security.AccessController;
  38 import java.security.PrivilegedAction;
  39 import java.security.PrivilegedActionException;
  40 import java.security.PrivilegedExceptionAction;
  41 import javax.management.*;
  42 import javax.management.openmbean.*;
  43 import static javax.management.openmbean.SimpleType.*;
  44 import com.sun.management.VMOption;
  45 
  46 /**
  47  * A mapped mxbean type maps a Java type to an open type.
  48  * Only the following Java types are mappable
  49  * (currently required by the platform MXBeans):
  50  *   1. Primitive types
  51  *   2. Wrapper classes such java.lang.Integer, etc
  52  *   3. Classes with only getter methods and with a static "from" method
  53  *      that takes a CompositeData argument.
  54  *   4. E[] where E is a type of 1-4 (can be multi-dimensional array)
  55  *   5. List<E> where E is a type of 1-3
  56  *   6. Map<K, V> where K and V are a type of 1-4
  57  *
  58  * OpenDataException will be thrown if a Java type is not supported.
  59  */
  60 // Suppress unchecked cast warnings at line 442, 523 and 546
  61 // Suppress unchecked calls at line 235, 284, 380 and 430.
  62 @SuppressWarnings("unchecked")
  63 public abstract class MappedMXBeanType {
  64     private static final WeakHashMap<Type,MappedMXBeanType> convertedTypes =


  96            final GenericArrayType t = (GenericArrayType) javaType;
  97            mt = new GenericArrayMXBeanType(t);
  98         }
  99         // No open type mapped for the javaType
 100         if (mt == null) {
 101             throw new OpenDataException(javaType +
 102                 " is not a supported MXBean type.");
 103         }
 104         convertedTypes.put(javaType, mt);
 105         return mt;
 106     }
 107 
 108     // basic types do not require data mapping
 109     static synchronized MappedMXBeanType newBasicType(Class<?> c, OpenType<?> ot)
 110             throws OpenDataException {
 111         MappedMXBeanType mt = new BasicMXBeanType(c, ot);
 112         convertedTypes.put(c, mt);
 113         return mt;
 114     }
 115 
 116     static synchronized MappedMXBeanType getMappedType(Type t)
 117             throws OpenDataException {
 118         MappedMXBeanType mt = convertedTypes.get(t);
 119         if (mt == null) {
 120             mt = newMappedType(t);
 121         }
 122 
 123         if (mt.getOpenType() instanceof InProgress) {
 124             throw new OpenDataException("Recursive data structure");
 125         }
 126         return mt;
 127     }
 128 
 129     // Convert a class to an OpenType
 130     public static synchronized OpenType<?> toOpenType(Type t)
 131             throws OpenDataException {
 132         MappedMXBeanType mt = getMappedType(t);
 133         return mt.getOpenType();
 134     }
 135 
 136     public static Object toJavaTypeData(Object openData, Type t)
 137             throws OpenDataException, InvalidObjectException {
 138         if (openData == null) {
 139             return null;
 140         }
 141         MappedMXBeanType mt = getMappedType(t);
 142         return mt.toJavaTypeData(openData);
 143     }
 144 
 145     public static Object toOpenTypeData(Object data, Type t)
 146             throws OpenDataException {
 147         if (data == null) {
 148             return null;
 149         }
 150         MappedMXBeanType mt = getMappedType(t);
 151         return mt.toOpenTypeData(data);
 152     }
 153 
 154     // Return the mapped open type
 155     OpenType<?> getOpenType() {
 156         return openType;
 157     }
 158 
 159     boolean isBasicType() {
 160         return isBasicType;
 161     }
 162 
 163     // Return the type name of the mapped open type
 164     // For primitive types, the type name is the same as the javaType
 165     // but the mapped open type is the wrapper class
 166     String getTypeName() {
 167         return getMappedTypeClass().getName();
 168     }
 169 
 170     // Return the mapped open type
 171     Class<?> getMappedTypeClass() {
 172         return mappedTypeClass;
 173     }
 174 
 175     abstract Type getJavaType();
 176 
 177     // return name of the class or the generic type
 178     abstract String getName();
 179 
 180     abstract Object toOpenTypeData(Object javaTypeData)
 181         throws OpenDataException;
 182 
 183     abstract Object toJavaTypeData(Object openTypeData)
 184         throws OpenDataException, InvalidObjectException;
 185 
 186     // Basic Types - Classes that do not require data conversion
 187     //               including primitive types and all SimpleType
 188     //
 189     //   Mapped open type: SimpleType for corresponding basic type
 190     //
 191     // Data Mapping:
 192     //   T <-> T (no conversion)
 193     //
 194     static class BasicMXBeanType extends MappedMXBeanType {
 195         final Class<?> basicType;
 196         BasicMXBeanType(Class<?> c, OpenType<?> openType) {
 197             this.basicType = c;
 198             this.openType = openType;
 199             this.mappedTypeClass = c;
 200             this.isBasicType = true;
 201         }
 202 
 203         Type getJavaType() {
 204             return basicType;
 205         }
 206 
 207         String getName() {
 208             return basicType.getName();
 209         }
 210 
 211         Object toOpenTypeData(Object data) throws OpenDataException {
 212             return data;
 213         }
 214 
 215         Object toJavaTypeData(Object data)
 216             throws OpenDataException, InvalidObjectException {
 217 
 218             return data;
 219         }
 220     }
 221 
 222 
 223     // Enum subclasses
 224     //   Mapped open type - String
 225     //
 226     // Data Mapping:
 227     //   Enum <-> enum's name
 228     //
 229     static class EnumMXBeanType extends MappedMXBeanType {
 230         @SuppressWarnings("rawtypes")
 231         final Class enumClass;
 232         EnumMXBeanType(Class<?> c) {
 233             this.enumClass = c;
 234             this.openType = STRING;
 235             this.mappedTypeClass = String.class;
 236         }
 237 
 238         Type getJavaType() {
 239             return enumClass;
 240         }
 241 
 242         String getName() {
 243             return enumClass.getName();
 244         }
 245 
 246         Object toOpenTypeData(Object data) throws OpenDataException {
 247             return ((Enum) data).name();
 248         }
 249 
 250         Object toJavaTypeData(Object data)
 251             throws OpenDataException, InvalidObjectException {
 252 
 253             try {
 254                 return Enum.valueOf(enumClass, (String) data);
 255             } catch (IllegalArgumentException e) {
 256                 // missing enum constants
 257                 final InvalidObjectException ioe =
 258                     new InvalidObjectException("Enum constant named " +
 259                     (String) data + " is missing");
 260                 ioe.initCause(e);
 261                 throw ioe;
 262             }
 263         }
 264     }
 265 
 266     // Array E[]
 267     //   Mapped open type - Array with element of OpenType for E
 268     //
 269     // Data Mapping:
 270     //   E[] <-> openTypeData(E)[]


 298                     new OpenDataException("Cannot obtain array class");
 299                 ode.initCause(e);
 300                 throw ode;
 301             }
 302 
 303             openType = new ArrayType<>(dim, baseElementType.getOpenType());
 304         }
 305 
 306         protected ArrayMXBeanType() {
 307             arrayClass = null;
 308         };
 309 
 310         Type getJavaType() {
 311             return arrayClass;
 312         }
 313 
 314         String getName() {
 315             return arrayClass.getName();
 316         }
 317 
 318         Object toOpenTypeData(Object data) throws OpenDataException {
 319             // If the base element type is a basic type
 320             // return the data as no conversion is needed.
 321             // Primitive types are not converted to wrappers.
 322             if (baseElementType.isBasicType()) {
 323                 return data;
 324             }
 325 
 326             final Object[] array = (Object[]) data;
 327             final Object[] openArray = (Object[])
 328                 Array.newInstance(componentType.getMappedTypeClass(),
 329                                   array.length);
 330             int i = 0;
 331             for (Object o : array) {
 332                 if (o == null) {
 333                     openArray[i] = null;
 334                 } else {
 335                     openArray[i] = componentType.toOpenTypeData(o);
 336                 }
 337                 i++;
 338             }
 339             return openArray;
 340         }
 341 
 342 
 343         Object toJavaTypeData(Object data)
 344             throws OpenDataException, InvalidObjectException {
 345 
 346             // If the base element type is a basic type
 347             // return the data as no conversion is needed.
 348             if (baseElementType.isBasicType()) {
 349                 return data;
 350             }
 351 
 352             final Object[] openArray = (Object[]) data;
 353             final Object[] array = (Object[])
 354                 Array.newInstance((Class) componentType.getJavaType(),
 355                                   openArray.length);
 356             int i = 0;
 357             for (Object o : openArray) {
 358                 if (o == null) {
 359                     array[i] = null;
 360                 } else {
 361                     array[i] = componentType.toJavaTypeData(o);
 362                 }
 363                 i++;


 440             try {
 441                 mappedTypeClass = Class.forName(
 442                     "[L" + paramType.getTypeName() + ";");
 443             } catch (ClassNotFoundException e) {
 444                 final OpenDataException ode =
 445                     new OpenDataException("Array class not found");
 446                 ode.initCause(e);
 447                 throw ode;
 448             }
 449             openType = new ArrayType<>(1, paramType.getOpenType());
 450         }
 451 
 452         Type getJavaType() {
 453             return javaType;
 454         }
 455 
 456         String getName() {
 457             return typeName;
 458         }
 459 
 460         Object toOpenTypeData(Object data) throws OpenDataException {
 461             final List<Object> list = (List<Object>) data;
 462 
 463             final Object[] openArray = (Object[])
 464                 Array.newInstance(paramType.getMappedTypeClass(),
 465                                   list.size());
 466             int i = 0;
 467             for (Object o : list) {
 468                 openArray[i++] = paramType.toOpenTypeData(o);
 469             }
 470             return openArray;
 471         }
 472 
 473         Object toJavaTypeData(Object data)
 474             throws OpenDataException, InvalidObjectException {
 475 
 476             final Object[] openArray = (Object[]) data;
 477             List<Object> result = new ArrayList<>(openArray.length);
 478             for (Object o : openArray) {
 479                 result.add(paramType.toJavaTypeData(o));
 480             }
 481             return result;
 482         }
 483     }
 484 
 485     private static final String KEY   = "key";
 486     private static final String VALUE = "value";
 487     private static final String[] mapIndexNames = {KEY};
 488     private static final String[] mapItemNames = {KEY, VALUE};
 489 
 490     // Map<K,V>
 491     //   Mapped open type - TabularType with row type:
 492     //                        CompositeType:
 493     //                          "key"   of openDataType(K)


 521                                             };
 522             final CompositeType rowType =
 523                 new CompositeType(typeName,
 524                                   typeName,
 525                                   mapItemNames,
 526                                   mapItemNames,
 527                                   mapItemTypes);
 528 
 529             openType = new TabularType(typeName, typeName, rowType, mapIndexNames);
 530             mappedTypeClass = javax.management.openmbean.TabularData.class;
 531         }
 532 
 533         Type getJavaType() {
 534             return javaType;
 535         }
 536 
 537         String getName() {
 538             return typeName;
 539         }
 540 
 541         Object toOpenTypeData(Object data) throws OpenDataException {
 542             final Map<Object,Object> map = (Map<Object,Object>) data;
 543             final TabularType tabularType = (TabularType) openType;
 544             final TabularData table = new TabularDataSupport(tabularType);
 545             final CompositeType rowType = tabularType.getRowType();
 546 
 547             for (Map.Entry<Object, Object> entry : map.entrySet()) {
 548                 final Object key = keyType.toOpenTypeData(entry.getKey());
 549                 final Object value = valueType.toOpenTypeData(entry.getValue());
 550                 final CompositeData row =
 551                     new CompositeDataSupport(rowType,
 552                                              mapItemNames,
 553                                              new Object[] {key, value});
 554                 table.put(row);
 555             }
 556             return table;
 557         }
 558 
 559         Object toJavaTypeData(Object data)
 560             throws OpenDataException, InvalidObjectException {
 561 
 562             final TabularData td = (TabularData) data;
 563 
 564             Map<Object, Object> result = new HashMap<>();
 565             for (CompositeData row : (Collection<CompositeData>) td.values()) {
 566                 Object key = keyType.toJavaTypeData(row.get(KEY));
 567                 Object value = valueType.toJavaTypeData(row.get(VALUE));
 568                 result.put(key, value);
 569             }
 570             return result;
 571         }
 572     }
 573 
 574     private static final Class<?> COMPOSITE_DATA_CLASS =
 575         javax.management.openmbean.CompositeData.class;
 576 
 577     // Classes that have a static from method
 578     //   Mapped open type - CompositeData
 579     //


 588     // The composite data view for this class will contain one
 589     // item entry for a "foo" attribute and the item type is
 590     // one of the open types defined in the OpenType class that
 591     // can be determined in the following manner:
 592     // o If FooType is a primitive type, the item type a wrapper
 593     //   class for the corresponding primitive type (such as
 594     //   Integer, Long, Boolean, etc).
 595     // o If FooType is of type CompositeData or TabularData,
 596     //   the item type is FooType.
 597     // o If FooType is an Enum, the item type is a String and
 598     //   the value is the name of the enum constant.
 599     // o If FooType is a class or an interface other than the above,
 600     //   the item type is CompositeData. The same convention
 601     //   can be recursively applied to the FooType class when
 602     //   constructing the composite data for the "foo" attribute.
 603     // o If FooType is an array, the item type is an array and
 604     //   its element type is determined as described above.
 605     //
 606     static class CompositeDataMXBeanType extends MappedMXBeanType {
 607         final Class<?> javaClass;
 608         final boolean isCompositeData;
 609         Method fromMethod = null;

 610 
 611         CompositeDataMXBeanType(Class<?> c) throws OpenDataException {
 612             this.javaClass = c;
 613             this.mappedTypeClass = COMPOSITE_DATA_CLASS;
 614 
 615             // check if a static from method exists
 616             try {
 617                 fromMethod = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
 618                         public Method run() throws NoSuchMethodException {
 619                             return javaClass.getMethod("from", COMPOSITE_DATA_CLASS);
 620                         }
 621                     });
 622             } catch (PrivilegedActionException e) {
 623                 // ignore NoSuchMethodException since we allow classes
 624                 // that has no from method to be embeded in another class.
 625             }
 626 




















 627             if (COMPOSITE_DATA_CLASS.isAssignableFrom(c)) {
 628                 // c implements CompositeData - set openType to null
 629                 // defer generating the CompositeType
 630                 // until the object is constructed
 631                 this.isCompositeData = true;
 632                 this.openType = null;
 633             } else {
 634                 this.isCompositeData = false;
 635 
 636                 // Make a CompositeData containing all the getters
 637                 final Method[] methods =
 638                     AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
 639                         public Method[] run() {
 640                             return javaClass.getMethods();
 641                         }
 642                     });
 643                 final List<String> names = new ArrayList<>();
 644                 final List<OpenType<?>> types = new ArrayList<>();
 645 
 646                 /* Select public methods that look like "T getX()" or "boolean


 674                     types.add(toOpenType(type));
 675                 }
 676 
 677                 final String[] nameArray = names.toArray(new String[0]);
 678                 openType = new CompositeType(c.getName(),
 679                                              c.getName(),
 680                                              nameArray, // field names
 681                                              nameArray, // field descriptions
 682                                              types.toArray(new OpenType<?>[0]));
 683             }
 684         }
 685 
 686         Type getJavaType() {
 687             return javaClass;
 688         }
 689 
 690         String getName() {
 691             return javaClass.getName();
 692         }
 693 
 694         Object toOpenTypeData(Object data) throws OpenDataException {
















 695             if (data instanceof MemoryUsage) {
 696                 return MemoryUsageCompositeData.toCompositeData((MemoryUsage) data);
 697             }
 698 
 699             if (data instanceof ThreadInfo) {
 700                 return ThreadInfoCompositeData.toCompositeData((ThreadInfo) data);
 701             }
 702 
 703             if (data instanceof LockInfo) {
 704                 if (data instanceof java.lang.management.MonitorInfo) {
 705                     return MonitorInfoCompositeData.toCompositeData((MonitorInfo) data);
 706                 }
 707                 return LockInfoCompositeData.toCompositeData((LockInfo) data);
 708             }
 709 
 710             if (data instanceof MemoryNotificationInfo) {
 711                 return MemoryNotifInfoCompositeData.
 712                     toCompositeData((MemoryNotificationInfo) data);
 713             }
 714 
 715             if (data instanceof VMOption) {
 716                 return VMOptionCompositeData.toCompositeData((VMOption) data);
 717             }
 718 
 719             if (isCompositeData) {
 720                 // Classes that implement CompositeData
 721                 //
 722                 // construct a new CompositeDataSupport object
 723                 // so that no other classes are sent over the wire
 724                 CompositeData cd = (CompositeData) data;
 725                 CompositeType ct = cd.getCompositeType();
 726                 String[] itemNames = ct.keySet().toArray(new String[0]);
 727                 Object[] itemValues = cd.getAll(itemNames);
 728                 return new CompositeDataSupport(ct, itemNames, itemValues);
 729             }
 730 
 731             throw new OpenDataException(javaClass.getName() +
 732                 " is not supported for platform MXBeans");
 733         }
 734 
 735         Object toJavaTypeData(Object data)
 736             throws OpenDataException, InvalidObjectException {
 737 
 738             if (fromMethod == null) {
 739                 throw new AssertionError("Does not support data conversion");
 740             }
 741 
 742             try {
 743                 return fromMethod.invoke(null, data);
 744             } catch (IllegalAccessException e) {
 745                 // should never reach here
 746                 throw new AssertionError(e);
 747             } catch (InvocationTargetException e) {
 748                 final OpenDataException ode =
 749                     new OpenDataException("Failed to invoke " +
 750                         fromMethod.getName() + " to convert CompositeData " +
 751                         " to " + javaClass.getName());
 752                 ode.initCause(e);
 753                 throw ode;
 754             }
 755         }


   1 /*
   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.
   4  *
   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
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.management;
  27 import java.lang.management.MemoryUsage;
  28 import java.lang.management.MemoryNotificationInfo;
  29 import java.lang.management.MonitorInfo;
  30 import java.lang.management.LockInfo;
  31 import java.lang.management.ThreadInfo;
  32 import java.lang.reflect.*;
  33 import java.util.List;
  34 import java.util.Map;
  35 import java.util.*;
  36 import java.io.InvalidObjectException;
  37 import java.security.AccessController;
  38 import java.security.PrivilegedAction;
  39 import java.security.PrivilegedActionException;
  40 import java.security.PrivilegedExceptionAction;

  41 import javax.management.openmbean.*;
  42 import static javax.management.openmbean.SimpleType.*;

  43 
  44 /**
  45  * A mapped mxbean type maps a Java type to an open type.
  46  * Only the following Java types are mappable
  47  * (currently required by the platform MXBeans):
  48  *   1. Primitive types
  49  *   2. Wrapper classes such java.lang.Integer, etc
  50  *   3. Classes with only getter methods and with a static "from" method
  51  *      that takes a CompositeData argument.
  52  *   4. E[] where E is a type of 1-4 (can be multi-dimensional array)
  53  *   5. List<E> where E is a type of 1-3
  54  *   6. Map<K, V> where K and V are a type of 1-4
  55  *
  56  * OpenDataException will be thrown if a Java type is not supported.
  57  */
  58 // Suppress unchecked cast warnings at line 442, 523 and 546
  59 // Suppress unchecked calls at line 235, 284, 380 and 430.
  60 @SuppressWarnings("unchecked")
  61 public abstract class MappedMXBeanType {
  62     private static final WeakHashMap<Type,MappedMXBeanType> convertedTypes =


  94            final GenericArrayType t = (GenericArrayType) javaType;
  95            mt = new GenericArrayMXBeanType(t);
  96         }
  97         // No open type mapped for the javaType
  98         if (mt == null) {
  99             throw new OpenDataException(javaType +
 100                 " is not a supported MXBean type.");
 101         }
 102         convertedTypes.put(javaType, mt);
 103         return mt;
 104     }
 105 
 106     // basic types do not require data mapping
 107     static synchronized MappedMXBeanType newBasicType(Class<?> c, OpenType<?> ot)
 108             throws OpenDataException {
 109         MappedMXBeanType mt = new BasicMXBeanType(c, ot);
 110         convertedTypes.put(c, mt);
 111         return mt;
 112     }
 113 
 114     public static synchronized MappedMXBeanType getMappedType(Type t)
 115             throws OpenDataException {
 116         MappedMXBeanType mt = convertedTypes.get(t);
 117         if (mt == null) {
 118             mt = newMappedType(t);
 119         }
 120 
 121         if (mt.getOpenType() instanceof InProgress) {
 122             throw new OpenDataException("Recursive data structure");
 123         }
 124         return mt;
 125     }
 126 
 127     // Convert a class to an OpenType
 128     public static synchronized OpenType<?> toOpenType(Type t)
 129             throws OpenDataException {
 130         MappedMXBeanType mt = getMappedType(t);
 131         return mt.getOpenType();
 132     }
 133 
 134     public static Object toJavaTypeData(Object openData, Type t)
 135             throws OpenDataException, InvalidObjectException {
 136         if (openData == null) {
 137             return null;
 138         }
 139         MappedMXBeanType mt = getMappedType(t);
 140         return mt.toJavaTypeData(openData);
 141     }
 142 
 143     public static Object toOpenTypeData(Object data, Type t)
 144             throws OpenDataException {
 145         if (data == null) {
 146             return null;
 147         }
 148         MappedMXBeanType mt = getMappedType(t);
 149         return mt.toOpenTypeData(data);
 150     }
 151 
 152     // Return the mapped open type
 153     public OpenType<?> getOpenType() {
 154         return openType;
 155     }
 156 
 157     boolean isBasicType() {
 158         return isBasicType;
 159     }
 160 
 161     // Return the type name of the mapped open type
 162     // For primitive types, the type name is the same as the javaType
 163     // but the mapped open type is the wrapper class
 164     String getTypeName() {
 165         return getMappedTypeClass().getName();
 166     }
 167 
 168     // Return the mapped open type
 169     Class<?> getMappedTypeClass() {
 170         return mappedTypeClass;
 171     }
 172 
 173     abstract Type getJavaType();
 174 
 175     // return name of the class or the generic type
 176     abstract String getName();
 177 
 178     public abstract Object toOpenTypeData(Object javaTypeData)
 179         throws OpenDataException;
 180 
 181     public abstract Object toJavaTypeData(Object openTypeData)
 182         throws OpenDataException, InvalidObjectException;
 183 
 184     // Basic Types - Classes that do not require data conversion
 185     //               including primitive types and all SimpleType
 186     //
 187     //   Mapped open type: SimpleType for corresponding basic type
 188     //
 189     // Data Mapping:
 190     //   T <-> T (no conversion)
 191     //
 192     static class BasicMXBeanType extends MappedMXBeanType {
 193         final Class<?> basicType;
 194         BasicMXBeanType(Class<?> c, OpenType<?> openType) {
 195             this.basicType = c;
 196             this.openType = openType;
 197             this.mappedTypeClass = c;
 198             this.isBasicType = true;
 199         }
 200 
 201         Type getJavaType() {
 202             return basicType;
 203         }
 204 
 205         String getName() {
 206             return basicType.getName();
 207         }
 208 
 209         public Object toOpenTypeData(Object data) throws OpenDataException {
 210             return data;
 211         }
 212 
 213         public Object toJavaTypeData(Object data)
 214             throws OpenDataException, InvalidObjectException {
 215 
 216             return data;
 217         }
 218     }
 219 
 220 
 221     // Enum subclasses
 222     //   Mapped open type - String
 223     //
 224     // Data Mapping:
 225     //   Enum <-> enum's name
 226     //
 227     static class EnumMXBeanType extends MappedMXBeanType {
 228         @SuppressWarnings("rawtypes")
 229         final Class enumClass;
 230         EnumMXBeanType(Class<?> c) {
 231             this.enumClass = c;
 232             this.openType = STRING;
 233             this.mappedTypeClass = String.class;
 234         }
 235 
 236         Type getJavaType() {
 237             return enumClass;
 238         }
 239 
 240         String getName() {
 241             return enumClass.getName();
 242         }
 243 
 244         public Object toOpenTypeData(Object data) throws OpenDataException {
 245             return ((Enum) data).name();
 246         }
 247 
 248         public Object toJavaTypeData(Object data)
 249             throws OpenDataException, InvalidObjectException {
 250 
 251             try {
 252                 return Enum.valueOf(enumClass, (String) data);
 253             } catch (IllegalArgumentException e) {
 254                 // missing enum constants
 255                 final InvalidObjectException ioe =
 256                     new InvalidObjectException("Enum constant named " +
 257                     (String) data + " is missing");
 258                 ioe.initCause(e);
 259                 throw ioe;
 260             }
 261         }
 262     }
 263 
 264     // Array E[]
 265     //   Mapped open type - Array with element of OpenType for E
 266     //
 267     // Data Mapping:
 268     //   E[] <-> openTypeData(E)[]


 296                     new OpenDataException("Cannot obtain array class");
 297                 ode.initCause(e);
 298                 throw ode;
 299             }
 300 
 301             openType = new ArrayType<>(dim, baseElementType.getOpenType());
 302         }
 303 
 304         protected ArrayMXBeanType() {
 305             arrayClass = null;
 306         };
 307 
 308         Type getJavaType() {
 309             return arrayClass;
 310         }
 311 
 312         String getName() {
 313             return arrayClass.getName();
 314         }
 315 
 316         public Object toOpenTypeData(Object data) throws OpenDataException {
 317             // If the base element type is a basic type
 318             // return the data as no conversion is needed.
 319             // Primitive types are not converted to wrappers.
 320             if (baseElementType.isBasicType()) {
 321                 return data;
 322             }
 323 
 324             final Object[] array = (Object[]) data;
 325             final Object[] openArray = (Object[])
 326                 Array.newInstance(componentType.getMappedTypeClass(),
 327                                   array.length);
 328             int i = 0;
 329             for (Object o : array) {
 330                 if (o == null) {
 331                     openArray[i] = null;
 332                 } else {
 333                     openArray[i] = componentType.toOpenTypeData(o);
 334                 }
 335                 i++;
 336             }
 337             return openArray;
 338         }
 339 
 340 
 341         public Object toJavaTypeData(Object data)
 342             throws OpenDataException, InvalidObjectException {
 343 
 344             // If the base element type is a basic type
 345             // return the data as no conversion is needed.
 346             if (baseElementType.isBasicType()) {
 347                 return data;
 348             }
 349 
 350             final Object[] openArray = (Object[]) data;
 351             final Object[] array = (Object[])
 352                 Array.newInstance((Class) componentType.getJavaType(),
 353                                   openArray.length);
 354             int i = 0;
 355             for (Object o : openArray) {
 356                 if (o == null) {
 357                     array[i] = null;
 358                 } else {
 359                     array[i] = componentType.toJavaTypeData(o);
 360                 }
 361                 i++;


 438             try {
 439                 mappedTypeClass = Class.forName(
 440                     "[L" + paramType.getTypeName() + ";");
 441             } catch (ClassNotFoundException e) {
 442                 final OpenDataException ode =
 443                     new OpenDataException("Array class not found");
 444                 ode.initCause(e);
 445                 throw ode;
 446             }
 447             openType = new ArrayType<>(1, paramType.getOpenType());
 448         }
 449 
 450         Type getJavaType() {
 451             return javaType;
 452         }
 453 
 454         String getName() {
 455             return typeName;
 456         }
 457 
 458         public Object toOpenTypeData(Object data) throws OpenDataException {
 459             final List<Object> list = (List<Object>) data;
 460 
 461             final Object[] openArray = (Object[])
 462                 Array.newInstance(paramType.getMappedTypeClass(),
 463                                   list.size());
 464             int i = 0;
 465             for (Object o : list) {
 466                 openArray[i++] = paramType.toOpenTypeData(o);
 467             }
 468             return openArray;
 469         }
 470 
 471         public Object toJavaTypeData(Object data)
 472             throws OpenDataException, InvalidObjectException {
 473 
 474             final Object[] openArray = (Object[]) data;
 475             List<Object> result = new ArrayList<>(openArray.length);
 476             for (Object o : openArray) {
 477                 result.add(paramType.toJavaTypeData(o));
 478             }
 479             return result;
 480         }
 481     }
 482 
 483     private static final String KEY   = "key";
 484     private static final String VALUE = "value";
 485     private static final String[] mapIndexNames = {KEY};
 486     private static final String[] mapItemNames = {KEY, VALUE};
 487 
 488     // Map<K,V>
 489     //   Mapped open type - TabularType with row type:
 490     //                        CompositeType:
 491     //                          "key"   of openDataType(K)


 519                                             };
 520             final CompositeType rowType =
 521                 new CompositeType(typeName,
 522                                   typeName,
 523                                   mapItemNames,
 524                                   mapItemNames,
 525                                   mapItemTypes);
 526 
 527             openType = new TabularType(typeName, typeName, rowType, mapIndexNames);
 528             mappedTypeClass = javax.management.openmbean.TabularData.class;
 529         }
 530 
 531         Type getJavaType() {
 532             return javaType;
 533         }
 534 
 535         String getName() {
 536             return typeName;
 537         }
 538 
 539         public Object toOpenTypeData(Object data) throws OpenDataException {
 540             final Map<Object,Object> map = (Map<Object,Object>) data;
 541             final TabularType tabularType = (TabularType) openType;
 542             final TabularData table = new TabularDataSupport(tabularType);
 543             final CompositeType rowType = tabularType.getRowType();
 544 
 545             for (Map.Entry<Object, Object> entry : map.entrySet()) {
 546                 final Object key = keyType.toOpenTypeData(entry.getKey());
 547                 final Object value = valueType.toOpenTypeData(entry.getValue());
 548                 final CompositeData row =
 549                     new CompositeDataSupport(rowType,
 550                                              mapItemNames,
 551                                              new Object[] {key, value});
 552                 table.put(row);
 553             }
 554             return table;
 555         }
 556 
 557         public Object toJavaTypeData(Object data)
 558             throws OpenDataException, InvalidObjectException {
 559 
 560             final TabularData td = (TabularData) data;
 561 
 562             Map<Object, Object> result = new HashMap<>();
 563             for (CompositeData row : (Collection<CompositeData>) td.values()) {
 564                 Object key = keyType.toJavaTypeData(row.get(KEY));
 565                 Object value = valueType.toJavaTypeData(row.get(VALUE));
 566                 result.put(key, value);
 567             }
 568             return result;
 569         }
 570     }
 571 
 572     private static final Class<?> COMPOSITE_DATA_CLASS =
 573         javax.management.openmbean.CompositeData.class;
 574 
 575     // Classes that have a static from method
 576     //   Mapped open type - CompositeData
 577     //


 586     // The composite data view for this class will contain one
 587     // item entry for a "foo" attribute and the item type is
 588     // one of the open types defined in the OpenType class that
 589     // can be determined in the following manner:
 590     // o If FooType is a primitive type, the item type a wrapper
 591     //   class for the corresponding primitive type (such as
 592     //   Integer, Long, Boolean, etc).
 593     // o If FooType is of type CompositeData or TabularData,
 594     //   the item type is FooType.
 595     // o If FooType is an Enum, the item type is a String and
 596     //   the value is the name of the enum constant.
 597     // o If FooType is a class or an interface other than the above,
 598     //   the item type is CompositeData. The same convention
 599     //   can be recursively applied to the FooType class when
 600     //   constructing the composite data for the "foo" attribute.
 601     // o If FooType is an array, the item type is an array and
 602     //   its element type is determined as described above.
 603     //
 604     static class CompositeDataMXBeanType extends MappedMXBeanType {
 605         final Class<?> javaClass;
 606         boolean isCompositeData = false;
 607         Method fromMethod = null;
 608         Method toMethod = null;
 609 
 610         CompositeDataMXBeanType(Class<?> c) throws OpenDataException {
 611             this.javaClass = c;
 612             this.mappedTypeClass = COMPOSITE_DATA_CLASS;
 613 
 614             // check if a static from method exists
 615             try {
 616                 fromMethod = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
 617                         public Method run() throws NoSuchMethodException {
 618                             return javaClass.getMethod("from", COMPOSITE_DATA_CLASS);
 619                         }
 620                     });
 621             } catch (PrivilegedActionException e) {
 622                 // ignore NoSuchMethodException since we allow classes
 623                 // that has no from method to be embeded in another class.
 624             }
 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 
 646             if (COMPOSITE_DATA_CLASS.isAssignableFrom(c)) {
 647                 // c implements CompositeData - set openType to null
 648                 // defer generating the CompositeType
 649                 // until the object is constructed
 650                 this.isCompositeData = true;
 651                 this.openType = null;
 652             } else {
 653                 this.isCompositeData = false;
 654 
 655                 // Make a CompositeData containing all the getters
 656                 final Method[] methods =
 657                     AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
 658                             public Method[] run() {
 659                                 return javaClass.getMethods();
 660                             }
 661                         });
 662                 final List<String> names = new ArrayList<>();
 663                 final List<OpenType<?>> types = new ArrayList<>();
 664 
 665                 /* Select public methods that look like "T getX()" or "boolean


 693                     types.add(toOpenType(type));
 694                 }
 695 
 696                 final String[] nameArray = names.toArray(new String[0]);
 697                 openType = new CompositeType(c.getName(),
 698                         c.getName(),
 699                         nameArray, // field names
 700                         nameArray, // field descriptions
 701                         types.toArray(new OpenType<?>[0]));
 702             }
 703         }
 704 
 705         Type getJavaType() {
 706             return javaClass;
 707         }
 708 
 709         String getName() {
 710             return javaClass.getName();
 711         }
 712 
 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 
 730             if (data instanceof MemoryUsage) {
 731                 return MemoryUsageCompositeData.toCompositeData((MemoryUsage) data);
 732             }
 733 
 734             if (data instanceof ThreadInfo) {
 735                 return ThreadInfoCompositeData.toCompositeData((ThreadInfo) data);
 736             }
 737 
 738             if (data instanceof LockInfo) {
 739                 if (data instanceof java.lang.management.MonitorInfo) {
 740                     return MonitorInfoCompositeData.toCompositeData((MonitorInfo) data);
 741                 }
 742                 return LockInfoCompositeData.toCompositeData((LockInfo) data);
 743             }
 744 
 745             if (data instanceof MemoryNotificationInfo) {
 746                 return MemoryNotifInfoCompositeData.
 747                     toCompositeData((MemoryNotificationInfo) data);
 748             }
 749 




 750             if (isCompositeData) {
 751                 // Classes that implement CompositeData
 752                 //
 753                 // construct a new CompositeDataSupport object
 754                 // so that no other classes are sent over the wire
 755                 CompositeData cd = (CompositeData) data;
 756                 CompositeType ct = cd.getCompositeType();
 757                 String[] itemNames = ct.keySet().toArray(new String[0]);
 758                 Object[] itemValues = cd.getAll(itemNames);
 759                 return new CompositeDataSupport(ct, itemNames, itemValues);
 760             }
 761 
 762             throw new OpenDataException(javaClass.getName() +
 763                 " is not supported for platform MXBeans");
 764         }
 765 
 766         public Object toJavaTypeData(Object data)
 767             throws OpenDataException, InvalidObjectException {
 768 
 769             if (fromMethod == null) {
 770                 throw new AssertionError("Does not support data conversion");
 771             }
 772 
 773             try {
 774                 return fromMethod.invoke(null, data);
 775             } catch (IllegalAccessException e) {
 776                 // should never reach here
 777                 throw new AssertionError(e);
 778             } catch (InvocationTargetException e) {
 779                 final OpenDataException ode =
 780                     new OpenDataException("Failed to invoke " +
 781                         fromMethod.getName() + " to convert CompositeData " +
 782                         " to " + javaClass.getName());
 783                 ode.initCause(e);
 784                 throw ode;
 785             }
 786         }


< prev index next >