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 }
|