📄 openconverter.java
字号:
makeParameterizedConverter(ParameterizedType objType) throws OpenDataException { final Type rawType = objType.getRawType(); if (rawType instanceof Class) { Class c = (Class<?>) rawType; if (c == List.class || c == Set.class || c == SortedSet.class) { Type[] actuals = ((ParameterizedType) objType).getActualTypeArguments(); assert(actuals.length == 1); if (c == SortedSet.class) mustBeComparable(c, actuals[0]); return makeArrayOrCollectionConverter(objType, actuals[0]); } else { boolean sortedMap = (c == SortedMap.class); if (c == Map.class || sortedMap) { Type[] actuals = ((ParameterizedType) objType).getActualTypeArguments(); assert(actuals.length == 2); if (sortedMap) mustBeComparable(c, actuals[0]); return makeTabularConverter(objType, sortedMap, actuals[0], actuals[1]); } } } throw new OpenDataException("Cannot convert type: " + objType); } private static OpenConverter makeMXBeanConverter(Type t) throws OpenDataException { return new MXBeanConverter(t); } private static OpenConverter makeCompositeConverter(Class c) throws OpenDataException { // For historical reasons GcInfo implements CompositeData but we // shouldn't count its CompositeData.getCompositeType() field as // an item in the computed CompositeType. final boolean gcInfoHack = (c.getName().equals("com.sun.management.GcInfo") && c.getClassLoader() == null); final List<Method> methods = MBeanAnalyzer.eliminateCovariantMethods(c.getMethods()); final SortedMap<String,Method> getterMap = newSortedMap(); /* Select public methods that look like "T getX()" or "boolean isX()", where T is not void and X is not the empty string. Exclude "Class getClass()" inherited from Object. */ for (Method method : methods) { final String propertyName = propertyName(method); if (propertyName == null) continue; if (gcInfoHack && propertyName.equals("CompositeType")) continue; Method old = getterMap.put(decapitalize(propertyName), method); if (old != null) { final String msg = "Class " + c.getName() + " has method name clash: " + old.getName() + ", " + method.getName(); throw new OpenDataException(msg); } } final int nitems = getterMap.size(); if (nitems == 0) { throw new OpenDataException("Can't map " + c.getName() + " to an open data type"); } final Method[] getters = new Method[nitems]; final String[] itemNames = new String[nitems]; final OpenType[] openTypes = new OpenType[nitems]; int i = 0; for (Map.Entry<String,Method> entry : getterMap.entrySet()) { itemNames[i] = entry.getKey(); final Method getter = entry.getValue(); getters[i] = getter; final Type retType = getter.getGenericReturnType(); openTypes[i] = toConverter(retType).getOpenType(); i++; } CompositeType compositeType = new CompositeType(c.getName(), c.getName(), itemNames, // field names itemNames, // field descriptions openTypes); return new CompositeConverter(c, compositeType, itemNames, getters); } /* Converter for classes where the open data is identical to the original data. This is true for any of the SimpleType types, and for an any-dimension array of those. It is also true for primitive types as of JMX 1.3, since an int[] needs to can be directly represented by an ArrayType, and an int needs no mapping because reflection takes care of it. */ private static final class IdentityConverter extends OpenConverter { IdentityConverter(Type targetType, OpenType openType, Class openClass) { super(targetType, openType, openClass); } boolean isIdentity() { return true; } final Object toNonNullOpenValue(MXBeanLookup lookup, Object value) { return value; } public final Object fromNonNullOpenValue(MXBeanLookup lookup, Object value) { return value; } } private static final class EnumConverter<T extends Enum<T>> extends OpenConverter { EnumConverter(Class<T> enumClass) { super(enumClass, SimpleType.STRING, String.class); this.enumClass = enumClass; } final Object toNonNullOpenValue(MXBeanLookup lookup, Object value) { return ((Enum) value).name(); } // return type could be T, but after erasure that would be // java.lang.Enum, which doesn't exist on J2SE 1.4 public final Object fromNonNullOpenValue(MXBeanLookup lookup, Object value) throws InvalidObjectException { try { return Enum.valueOf(enumClass, (String) value); } catch (Exception e) { throw invalidObjectException("Cannot convert to enum: " + value, e); } } private final Class<T> enumClass; } private static final class ArrayConverter extends OpenConverter { ArrayConverter(Type targetType, ArrayType openArrayType, Class openArrayClass, OpenConverter elementConverter) { super(targetType, openArrayType, openArrayClass); this.elementConverter = elementConverter; } final Object toNonNullOpenValue(MXBeanLookup lookup, Object value) throws OpenDataException { Object[] valueArray = (Object[]) value; final int len = valueArray.length; final Object[] openArray = (Object[]) Array.newInstance(getOpenClass().getComponentType(), len); for (int i = 0; i < len; i++) { openArray[i] = elementConverter.toOpenValue(lookup, valueArray[i]); } return openArray; } public final Object fromNonNullOpenValue(MXBeanLookup lookup, Object openValue) throws InvalidObjectException { final Object[] openArray = (Object[]) openValue; final Type targetType = getTargetType(); final Object[] valueArray; final Type componentType; if (targetType instanceof GenericArrayType) { componentType = ((GenericArrayType) targetType).getGenericComponentType(); } else if (targetType instanceof Class && ((Class<?>) targetType).isArray()) { componentType = ((Class<?>) targetType).getComponentType(); } else { throw new IllegalArgumentException("Not an array: " + targetType); } valueArray = (Object[]) Array.newInstance((Class<?>) componentType, openArray.length); for (int i = 0; i < openArray.length; i++) { valueArray[i] = elementConverter.fromOpenValue(lookup, openArray[i]); } return valueArray; } void checkReconstructible() throws InvalidObjectException { elementConverter.checkReconstructible(); } /** OpenConverter for the elements of this array. If this is an array of arrays, the converter converts the second-level arrays, not the deepest elements. */ private final OpenConverter elementConverter; } private static final class CollectionConverter extends OpenConverter { CollectionConverter(Type targetType, ArrayType openArrayType, Class openArrayClass, OpenConverter elementConverter) { super(targetType, openArrayType, openArrayClass); this.elementConverter = elementConverter; /* Determine the concrete class to be used when converting back to this Java type. We convert all Lists to ArrayList and all Sets to TreeSet. (TreeSet because it is a SortedSet, so works for both Set and SortedSet.) */ Type raw = ((ParameterizedType) targetType).getRawType(); Class c = (Class<?>) raw; if (c == List.class) collectionClass = ArrayList.class; else if (c == Set.class) collectionClass = HashSet.class; else if (c == SortedSet.class) collectionClass = TreeSet.class; else { // can't happen assert(false); collectionClass = null; } } final Object toNonNullOpenValue(MXBeanLookup lookup, Object value) throws OpenDataException { final Collection valueCollection = (Collection) value; if (valueCollection instanceof SortedSet) { Comparator comparator = ((SortedSet) valueCollection).comparator(); if (comparator != null) { final String msg = "Cannot convert SortedSet with non-null comparator: " + comparator; throw openDataException(msg, new IllegalArgumentException(msg)); } } final Object[] openArray = (Object[]) Array.newInstance(getOpenClass().getComponentType(), valueCollection.size()); int i = 0; for (Object o : valueCollection) openArray[i++] = elementConverter.toOpenValue(lookup, o); return openArray; } public final Object fromNonNullOpenValue(MXBeanLookup lookup, Object openValue) throws InvalidObjectException { final Object[] openArray = (Object[]) openValue; final Collection<Object> valueCollection; try { valueCollection = collectionClass.newInstance(); } catch (Exception e) { throw invalidObjectException("Cannot create collection", e); } for (Object o : openArray) { Object value = elementConverter.fromOpenValue(lookup, o); if (!valueCollection.add(value)) { final String msg = "Could not add " + o + " to " + collectionClass.getName() + " (duplicate set element?)"; throw new InvalidObjectException(msg); } } return valueCollection; } void checkReconstructible() throws InvalidObjectException { elementConverter.checkReconstructible(); } private final Class<? extends Collection> collectionClass; private final OpenConverter elementConverter; } private static final class MXBeanConverter extends OpenConverter { MXBeanConverter(Type intf) { super(intf, SimpleType.OBJECTNAME, ObjectName.class); } final Object toNonNullOpenValue(MXBeanLookup lookup, Object value) throws OpenDataException { lookupNotNull(lookup, OpenDataException.class); ObjectName name = lookup.mxbeanToObjectName(value); if (name == null) throw new OpenDataException("No name for object: " + value); return name; } public final Object fromNonNullOpenValue(MXBeanLookup lookup, Object value) throws InvalidObjectException { lookupNotNull(lookup, InvalidObjectException.class); ObjectName name = (ObjectName) value; Object mxbean = lookup.objectNameToMXBean(name, (Class<?>) getTargetType()); if (mxbean == null) { final String msg = "No MXBean for name: " + name; throw new InvalidObjectException(msg); } return mxbean; } private <T extends Exception> void lookupNotNull(MXBeanLookup lookup, Class<T> excClass) throws T { if (lookup == null) { final String msg = "Cannot convert MXBean interface in this context"; T exc; try { Constructor<T> con = excClass.getConstructor(String.class); exc = con.newInstance(msg); } catch (Exception e) { throw new RuntimeException(e); } throw exc; } } } private static final class TabularConverter extends OpenConverter { TabularConverter(Type targetType, boolean sortedMap, TabularType tabularType, OpenConverter keyConverter, OpenConverter valueConverter) { super(targetType, tabularType, TabularData.class); this.sortedMap = sortedMap; this.keyConverter = keyConverter; this.valueConverter = valueConverter; } final Object toNonNullOpenValue(MXBeanLookup lookup, Object value) throws OpenDataException { final Map<Object, Object> valueMap = (Map<Object, Object>) value; if (valueMap instanceof SortedMap) { Comparator comparator = ((SortedMap) valueMap).comparator(); if (comparator != null) { final String msg = "Cannot convert SortedMap with non-null comparator: " + comparator; IllegalArgumentException iae = new IllegalArgumentException(msg); OpenDataException ode = new OpenDataException(msg); ode.initCause(iae); throw ode; } } final TabularType tabularType = (TabularType) getOpenType(); final TabularData table = new TabularDataSupport(tabularType); final CompositeType rowType = tabularType.getRowType(); for (Map.Entry entry : valueMap.entrySet()) { final Object openKey = keyConverter.toOpenValue(lookup, entry.getKey()); final Object openValue = valueConverter.toOpenValue(lookup, entry.getValue()); final CompositeData row; row = new CompositeDataSupport(rowType, keyValueArray, new Object[] {openKey, openValue}); table.put(row); } return table; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -