60 // Suppress unchecked cast warnings at line 442, 523 and 546 |
60 // Suppress unchecked cast warnings at line 442, 523 and 546 |
61 // Suppress unchecked calls at line 235, 284, 380 and 430. |
61 // Suppress unchecked calls at line 235, 284, 380 and 430. |
62 @SuppressWarnings("unchecked") |
62 @SuppressWarnings("unchecked") |
63 public abstract class MappedMXBeanType { |
63 public abstract class MappedMXBeanType { |
64 private static final WeakHashMap<Type,MappedMXBeanType> convertedTypes = |
64 private static final WeakHashMap<Type,MappedMXBeanType> convertedTypes = |
65 new WeakHashMap<Type,MappedMXBeanType>(); |
65 new WeakHashMap<>(); |
66 |
66 |
67 boolean isBasicType = false; |
67 boolean isBasicType = false; |
68 OpenType openType = inProgress; |
68 OpenType<?> openType = inProgress; |
69 Class mappedTypeClass; |
69 Class<?> mappedTypeClass; |
70 |
70 |
71 static synchronized MappedMXBeanType newMappedType(Type javaType) |
71 static synchronized MappedMXBeanType newMappedType(Type javaType) |
72 throws OpenDataException { |
72 throws OpenDataException { |
73 |
73 |
74 MappedMXBeanType mt = null; |
74 MappedMXBeanType mt = null; |
75 if (javaType instanceof Class) { |
75 if (javaType instanceof Class) { |
76 final Class c = (Class) javaType; |
76 final Class<?> c = (Class<?>) javaType; |
77 if (c.isEnum()) { |
77 if (c.isEnum()) { |
78 mt = new EnumMXBeanType(c); |
78 mt = new EnumMXBeanType(c); |
79 } else if (c.isArray()) { |
79 } else if (c.isArray()) { |
80 mt = new ArrayMXBeanType(c); |
80 mt = new ArrayMXBeanType(c); |
81 } else { |
81 } else { |
83 } |
83 } |
84 } else if (javaType instanceof ParameterizedType) { |
84 } else if (javaType instanceof ParameterizedType) { |
85 final ParameterizedType pt = (ParameterizedType) javaType; |
85 final ParameterizedType pt = (ParameterizedType) javaType; |
86 final Type rawType = pt.getRawType(); |
86 final Type rawType = pt.getRawType(); |
87 if (rawType instanceof Class) { |
87 if (rawType instanceof Class) { |
88 final Class rc = (Class) rawType; |
88 final Class<?> rc = (Class<?>) rawType; |
89 if (rc == List.class) { |
89 if (rc == List.class) { |
90 mt = new ListMXBeanType(pt); |
90 mt = new ListMXBeanType(pt); |
91 } else if (rc == Map.class) { |
91 } else if (rc == Map.class) { |
92 mt = new MapMXBeanType(pt); |
92 mt = new MapMXBeanType(pt); |
93 } |
93 } |
104 convertedTypes.put(javaType, mt); |
104 convertedTypes.put(javaType, mt); |
105 return mt; |
105 return mt; |
106 } |
106 } |
107 |
107 |
108 // basic types do not require data mapping |
108 // basic types do not require data mapping |
109 static synchronized MappedMXBeanType newBasicType(Class c, OpenType ot) |
109 static synchronized MappedMXBeanType newBasicType(Class<?> c, OpenType<?> ot) |
110 throws OpenDataException { |
110 throws OpenDataException { |
111 MappedMXBeanType mt = new BasicMXBeanType(c, ot); |
111 MappedMXBeanType mt = new BasicMXBeanType(c, ot); |
112 convertedTypes.put(c, mt); |
112 convertedTypes.put(c, mt); |
113 return mt; |
113 return mt; |
114 } |
114 } |
125 } |
125 } |
126 return mt; |
126 return mt; |
127 } |
127 } |
128 |
128 |
129 // Convert a class to an OpenType |
129 // Convert a class to an OpenType |
130 public static synchronized OpenType toOpenType(Type t) |
130 public static synchronized OpenType<?> toOpenType(Type t) |
131 throws OpenDataException { |
131 throws OpenDataException { |
132 MappedMXBeanType mt = getMappedType(t); |
132 MappedMXBeanType mt = getMappedType(t); |
133 return mt.getOpenType(); |
133 return mt.getOpenType(); |
134 } |
134 } |
135 |
135 |
150 MappedMXBeanType mt = getMappedType(t); |
150 MappedMXBeanType mt = getMappedType(t); |
151 return mt.toOpenTypeData(data); |
151 return mt.toOpenTypeData(data); |
152 } |
152 } |
153 |
153 |
154 // Return the mapped open type |
154 // Return the mapped open type |
155 OpenType getOpenType() { |
155 OpenType<?> getOpenType() { |
156 return openType; |
156 return openType; |
157 } |
157 } |
158 |
158 |
159 boolean isBasicType() { |
159 boolean isBasicType() { |
160 return isBasicType; |
160 return isBasicType; |
166 String getTypeName() { |
166 String getTypeName() { |
167 return getMappedTypeClass().getName(); |
167 return getMappedTypeClass().getName(); |
168 } |
168 } |
169 |
169 |
170 // Return the mapped open type |
170 // Return the mapped open type |
171 Class getMappedTypeClass() { |
171 Class<?> getMappedTypeClass() { |
172 return mappedTypeClass; |
172 return mappedTypeClass; |
173 } |
173 } |
174 |
174 |
175 abstract Type getJavaType(); |
175 abstract Type getJavaType(); |
176 |
176 |
190 // |
190 // |
191 // Data Mapping: |
191 // Data Mapping: |
192 // T <-> T (no conversion) |
192 // T <-> T (no conversion) |
193 // |
193 // |
194 static class BasicMXBeanType extends MappedMXBeanType { |
194 static class BasicMXBeanType extends MappedMXBeanType { |
195 final Class basicType; |
195 final Class<?> basicType; |
196 BasicMXBeanType(Class c, OpenType openType) { |
196 BasicMXBeanType(Class<?> c, OpenType<?> openType) { |
197 this.basicType = c; |
197 this.basicType = c; |
198 this.openType = openType; |
198 this.openType = openType; |
199 this.mappedTypeClass = c; |
199 this.mappedTypeClass = c; |
200 this.isBasicType = true; |
200 this.isBasicType = true; |
201 } |
201 } |
226 // Data Mapping: |
226 // Data Mapping: |
227 // Enum <-> enum's name |
227 // Enum <-> enum's name |
228 // |
228 // |
229 static class EnumMXBeanType extends MappedMXBeanType { |
229 static class EnumMXBeanType extends MappedMXBeanType { |
230 final Class enumClass; |
230 final Class enumClass; |
231 EnumMXBeanType(Class c) { |
231 EnumMXBeanType(Class<?> c) { |
232 this.enumClass = c; |
232 this.enumClass = c; |
233 this.openType = STRING; |
233 this.openType = STRING; |
234 this.mappedTypeClass = String.class; |
234 this.mappedTypeClass = String.class; |
235 } |
235 } |
236 |
236 |
267 // |
267 // |
268 // Data Mapping: |
268 // Data Mapping: |
269 // E[] <-> openTypeData(E)[] |
269 // E[] <-> openTypeData(E)[] |
270 // |
270 // |
271 static class ArrayMXBeanType extends MappedMXBeanType { |
271 static class ArrayMXBeanType extends MappedMXBeanType { |
272 final Class arrayClass; |
272 final Class<?> arrayClass; |
273 protected MappedMXBeanType componentType; |
273 protected MappedMXBeanType componentType; |
274 protected MappedMXBeanType baseElementType; |
274 protected MappedMXBeanType baseElementType; |
275 |
275 |
276 ArrayMXBeanType(Class c) throws OpenDataException { |
276 ArrayMXBeanType(Class<?> c) throws OpenDataException { |
277 this.arrayClass = c; |
277 this.arrayClass = c; |
278 this.componentType = getMappedType(c.getComponentType()); |
278 this.componentType = getMappedType(c.getComponentType()); |
279 |
279 |
280 StringBuilder className = new StringBuilder(); |
280 StringBuilder className = new StringBuilder(); |
281 Class et = c; |
281 Class<?> et = c; |
282 int dim; |
282 int dim; |
283 for (dim = 0; et.isArray(); dim++) { |
283 for (dim = 0; et.isArray(); dim++) { |
284 className.append('['); |
284 className.append('['); |
285 et = et.getComponentType(); |
285 et = et.getComponentType(); |
286 } |
286 } |
426 |
426 |
427 if (!(argTypes[0] instanceof Class)) { |
427 if (!(argTypes[0] instanceof Class)) { |
428 throw new OpenDataException("Element Type for " + pt + |
428 throw new OpenDataException("Element Type for " + pt + |
429 " not supported"); |
429 " not supported"); |
430 } |
430 } |
431 final Class et = (Class) argTypes[0]; |
431 final Class<?> et = (Class<?>) argTypes[0]; |
432 if (et.isArray()) { |
432 if (et.isArray()) { |
433 throw new OpenDataException("Element Type for " + pt + |
433 throw new OpenDataException("Element Type for " + pt + |
434 " not supported"); |
434 " not supported"); |
435 } |
435 } |
436 paramType = getMappedType(et); |
436 paramType = getMappedType(et); |
471 |
471 |
472 Object toJavaTypeData(Object data) |
472 Object toJavaTypeData(Object data) |
473 throws OpenDataException, InvalidObjectException { |
473 throws OpenDataException, InvalidObjectException { |
474 |
474 |
475 final Object[] openArray = (Object[]) data; |
475 final Object[] openArray = (Object[]) data; |
476 List<Object> result = new ArrayList<Object>(openArray.length); |
476 List<Object> result = new ArrayList<>(openArray.length); |
477 for (Object o : openArray) { |
477 for (Object o : openArray) { |
478 result.add(paramType.toJavaTypeData(o)); |
478 result.add(paramType.toJavaTypeData(o)); |
479 } |
479 } |
480 return result; |
480 return result; |
481 } |
481 } |
512 |
512 |
513 |
513 |
514 // FIXME: generate typeName for generic |
514 // FIXME: generate typeName for generic |
515 typeName = "Map<" + keyType.getName() + "," + |
515 typeName = "Map<" + keyType.getName() + "," + |
516 valueType.getName() + ">"; |
516 valueType.getName() + ">"; |
517 final OpenType[] mapItemTypes = new OpenType[] { |
517 final OpenType<?>[] mapItemTypes = new OpenType<?>[] { |
518 keyType.getOpenType(), |
518 keyType.getOpenType(), |
519 valueType.getOpenType(), |
519 valueType.getOpenType(), |
520 }; |
520 }; |
521 final CompositeType rowType = |
521 final CompositeType rowType = |
522 new CompositeType(typeName, |
522 new CompositeType(typeName, |
541 final Map<Object,Object> map = (Map<Object,Object>) data; |
541 final Map<Object,Object> map = (Map<Object,Object>) data; |
542 final TabularType tabularType = (TabularType) openType; |
542 final TabularType tabularType = (TabularType) openType; |
543 final TabularData table = new TabularDataSupport(tabularType); |
543 final TabularData table = new TabularDataSupport(tabularType); |
544 final CompositeType rowType = tabularType.getRowType(); |
544 final CompositeType rowType = tabularType.getRowType(); |
545 |
545 |
546 for (Map.Entry entry : map.entrySet()) { |
546 for (Map.Entry<Object, Object> entry : map.entrySet()) { |
547 final Object key = keyType.toOpenTypeData(entry.getKey()); |
547 final Object key = keyType.toOpenTypeData(entry.getKey()); |
548 final Object value = valueType.toOpenTypeData(entry.getValue()); |
548 final Object value = valueType.toOpenTypeData(entry.getValue()); |
549 final CompositeData row = |
549 final CompositeData row = |
550 new CompositeDataSupport(rowType, |
550 new CompositeDataSupport(rowType, |
551 mapItemNames, |
551 mapItemNames, |
558 Object toJavaTypeData(Object data) |
558 Object toJavaTypeData(Object data) |
559 throws OpenDataException, InvalidObjectException { |
559 throws OpenDataException, InvalidObjectException { |
560 |
560 |
561 final TabularData td = (TabularData) data; |
561 final TabularData td = (TabularData) data; |
562 |
562 |
563 Map<Object, Object> result = new HashMap<Object, Object>(); |
563 Map<Object, Object> result = new HashMap<>(); |
564 for (CompositeData row : (Collection<CompositeData>) td.values()) { |
564 for (CompositeData row : (Collection<CompositeData>) td.values()) { |
565 Object key = keyType.toJavaTypeData(row.get(KEY)); |
565 Object key = keyType.toJavaTypeData(row.get(KEY)); |
566 Object value = valueType.toJavaTypeData(row.get(VALUE)); |
566 Object value = valueType.toJavaTypeData(row.get(VALUE)); |
567 result.put(key, value); |
567 result.put(key, value); |
568 } |
568 } |
605 static class CompositeDataMXBeanType extends MappedMXBeanType { |
605 static class CompositeDataMXBeanType extends MappedMXBeanType { |
606 final Class<?> javaClass; |
606 final Class<?> javaClass; |
607 final boolean isCompositeData; |
607 final boolean isCompositeData; |
608 Method fromMethod = null; |
608 Method fromMethod = null; |
609 |
609 |
610 CompositeDataMXBeanType(Class c) throws OpenDataException { |
610 CompositeDataMXBeanType(Class<?> c) throws OpenDataException { |
611 this.javaClass = c; |
611 this.javaClass = c; |
612 this.mappedTypeClass = COMPOSITE_DATA_CLASS; |
612 this.mappedTypeClass = COMPOSITE_DATA_CLASS; |
613 |
613 |
614 // check if a static from method exists |
614 // check if a static from method exists |
615 try { |
615 try { |
637 AccessController.doPrivileged(new PrivilegedAction<Method[]>() { |
637 AccessController.doPrivileged(new PrivilegedAction<Method[]>() { |
638 public Method[] run() { |
638 public Method[] run() { |
639 return javaClass.getMethods(); |
639 return javaClass.getMethods(); |
640 } |
640 } |
641 }); |
641 }); |
642 final List<String> names = new ArrayList<String>(); |
642 final List<String> names = new ArrayList<>(); |
643 final List<OpenType> types = new ArrayList<OpenType>(); |
643 final List<OpenType<?>> types = new ArrayList<>(); |
644 |
644 |
645 /* Select public methods that look like "T getX()" or "boolean |
645 /* Select public methods that look like "T getX()" or "boolean |
646 isX()", where T is not void and X is not the empty |
646 isX()", where T is not void and X is not the empty |
647 string. Exclude "Class getClass()" inherited from Object. */ |
647 string. Exclude "Class getClass()" inherited from Object. */ |
648 for (int i = 0; i < methods.length; i++) { |
648 for (int i = 0; i < methods.length; i++) { |
676 final String[] nameArray = names.toArray(new String[0]); |
676 final String[] nameArray = names.toArray(new String[0]); |
677 openType = new CompositeType(c.getName(), |
677 openType = new CompositeType(c.getName(), |
678 c.getName(), |
678 c.getName(), |
679 nameArray, // field names |
679 nameArray, // field names |
680 nameArray, // field descriptions |
680 nameArray, // field descriptions |
681 types.toArray(new OpenType[0])); |
681 types.toArray(new OpenType<?>[0])); |
682 } |
682 } |
683 } |
683 } |
684 |
684 |
685 Type getJavaType() { |
685 Type getJavaType() { |
686 return javaClass; |
686 return javaClass; |
720 // |
720 // |
721 // construct a new CompositeDataSupport object |
721 // construct a new CompositeDataSupport object |
722 // so that no other classes are sent over the wire |
722 // so that no other classes are sent over the wire |
723 CompositeData cd = (CompositeData) data; |
723 CompositeData cd = (CompositeData) data; |
724 CompositeType ct = cd.getCompositeType(); |
724 CompositeType ct = cd.getCompositeType(); |
725 String[] itemNames = (String[]) ct.keySet().toArray(new String[0]); |
725 String[] itemNames = ct.keySet().toArray(new String[0]); |
726 Object[] itemValues = cd.getAll(itemNames); |
726 Object[] itemValues = cd.getAll(itemNames); |
727 return new CompositeDataSupport(ct, itemNames, itemValues); |
727 return new CompositeDataSupport(ct, itemNames, itemValues); |
728 } |
728 } |
729 |
729 |
730 throw new OpenDataException(javaClass.getName() + |
730 throw new OpenDataException(javaClass.getName() + |
777 public boolean isValue(Object o) { |
777 public boolean isValue(Object o) { |
778 return false; |
778 return false; |
779 } |
779 } |
780 private static final long serialVersionUID = -3413063475064374490L; |
780 private static final long serialVersionUID = -3413063475064374490L; |
781 } |
781 } |
782 private static final OpenType inProgress; |
782 private static final OpenType<?> inProgress; |
783 static { |
783 static { |
784 OpenType t; |
784 OpenType<?> t; |
785 try { |
785 try { |
786 t = new InProgress(); |
786 t = new InProgress(); |
787 } catch (OpenDataException e) { |
787 } catch (OpenDataException e) { |
788 // Should not reach here |
788 // Should not reach here |
789 throw new AssertionError(e); |
789 throw new AssertionError(e); |
797 VOID, |
797 VOID, |
798 }; |
798 }; |
799 static { |
799 static { |
800 try { |
800 try { |
801 for (int i = 0; i < simpleTypes.length; i++) { |
801 for (int i = 0; i < simpleTypes.length; i++) { |
802 final OpenType t = simpleTypes[i]; |
802 final OpenType<?> t = simpleTypes[i]; |
803 Class c; |
803 Class<?> c; |
804 try { |
804 try { |
805 c = Class.forName(t.getClassName(), false, |
805 c = Class.forName(t.getClassName(), false, |
806 String.class.getClassLoader()); |
806 String.class.getClassLoader()); |
807 MappedMXBeanType.newBasicType(c, t); |
807 MappedMXBeanType.newBasicType(c, t); |
808 } catch (ClassNotFoundException e) { |
808 } catch (ClassNotFoundException e) { |
814 } |
814 } |
815 |
815 |
816 if (c.getName().startsWith("java.lang.")) { |
816 if (c.getName().startsWith("java.lang.")) { |
817 try { |
817 try { |
818 final Field typeField = c.getField("TYPE"); |
818 final Field typeField = c.getField("TYPE"); |
819 final Class primitiveType = (Class) typeField.get(null); |
819 final Class<?> primitiveType = (Class<?>) typeField.get(null); |
820 MappedMXBeanType.newBasicType(primitiveType, t); |
820 MappedMXBeanType.newBasicType(primitiveType, t); |
821 } catch (NoSuchFieldException e) { |
821 } catch (NoSuchFieldException e) { |
822 // OK: must not be a primitive wrapper |
822 // OK: must not be a primitive wrapper |
823 } catch (IllegalAccessException e) { |
823 } catch (IllegalAccessException e) { |
824 // Should not reach here |
824 // Should not reach here |