| /* |
| * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package sun.management; |
| import java.lang.management.MemoryUsage; |
| import java.lang.management.MemoryNotificationInfo; |
| import java.lang.management.MonitorInfo; |
| import java.lang.management.LockInfo; |
| import java.lang.management.ThreadInfo; |
| import java.lang.reflect.*; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.*; |
| import java.io.InvalidObjectException; |
| import java.security.AccessController; |
| import java.security.PrivilegedAction; |
| import java.security.PrivilegedActionException; |
| import java.security.PrivilegedExceptionAction; |
| import javax.management.*; |
| import javax.management.openmbean.*; |
| import static javax.management.openmbean.SimpleType.*; |
| import com.sun.management.VMOption; |
| |
| /** |
| * A mapped mxbean type maps a Java type to an open type. |
| * Only the following Java types are mappable |
| * (currently required by the platform MXBeans): |
| * 1. Primitive types |
| * 2. Wrapper classes such java.lang.Integer, etc |
| * 3. Classes with only getter methods and with a static "from" method |
| * that takes a CompositeData argument. |
| * 4. E[] where E is a type of 1-4 (can be multi-dimensional array) |
| * 5. List<E> where E is a type of 1-3 |
| * 6. Map<K, V> where K and V are a type of 1-4 |
| * |
| * OpenDataException will be thrown if a Java type is not supported. |
| */ |
| // Suppress unchecked cast warnings at line 442, 523 and 546 |
| // Suppress unchecked calls at line 235, 284, 380 and 430. |
| @SuppressWarnings("unchecked") |
| public abstract class MappedMXBeanType { |
| private static final WeakHashMap<Type,MappedMXBeanType> convertedTypes = |
| new WeakHashMap<Type,MappedMXBeanType>(); |
| |
| boolean isBasicType = false; |
| OpenType openType = inProgress; |
| Class mappedTypeClass; |
| |
| static synchronized MappedMXBeanType newMappedType(Type javaType) |
| throws OpenDataException { |
| |
| MappedMXBeanType mt = null; |
| if (javaType instanceof Class) { |
| final Class c = (Class) javaType; |
| if (c.isEnum()) { |
| mt = new EnumMXBeanType(c); |
| } else if (c.isArray()) { |
| mt = new ArrayMXBeanType(c); |
| } else { |
| mt = new CompositeDataMXBeanType(c); |
| } |
| } else if (javaType instanceof ParameterizedType) { |
| final ParameterizedType pt = (ParameterizedType) javaType; |
| final Type rawType = pt.getRawType(); |
| if (rawType instanceof Class) { |
| final Class rc = (Class) rawType; |
| if (rc == List.class) { |
| mt = new ListMXBeanType(pt); |
| } else if (rc == Map.class) { |
| mt = new MapMXBeanType(pt); |
| } |
| } |
| } else if (javaType instanceof GenericArrayType) { |
| final GenericArrayType t = (GenericArrayType) javaType; |
| mt = new GenericArrayMXBeanType(t); |
| } |
| // No open type mapped for the javaType |
| if (mt == null) { |
| throw new OpenDataException(javaType + |
| " is not a supported MXBean type."); |
| } |
| convertedTypes.put(javaType, mt); |
| return mt; |
| } |
| |
| // basic types do not require data mapping |
| static synchronized MappedMXBeanType newBasicType(Class c, OpenType ot) |
| throws OpenDataException { |
| MappedMXBeanType mt = new BasicMXBeanType(c, ot); |
| convertedTypes.put(c, mt); |
| return mt; |
| } |
| |
| static synchronized MappedMXBeanType getMappedType(Type t) |
| throws OpenDataException { |
| MappedMXBeanType mt = convertedTypes.get(t); |
| if (mt == null) { |
| mt = newMappedType(t); |
| } |
| |
| if (mt.getOpenType() instanceof InProgress) { |
| throw new OpenDataException("Recursive data structure"); |
| } |
| return mt; |
| } |
| |
| // Convert a class to an OpenType |
| public static synchronized OpenType toOpenType(Type t) |
| throws OpenDataException { |
| MappedMXBeanType mt = getMappedType(t); |
| return mt.getOpenType(); |
| } |
| |
| public static Object toJavaTypeData(Object openData, Type t) |
| throws OpenDataException, InvalidObjectException { |
| if (openData == null) { |
| return null; |
| } |
| MappedMXBeanType mt = getMappedType(t); |
| return mt.toJavaTypeData(openData); |
| } |
| |
| public static Object toOpenTypeData(Object data, Type t) |
| throws OpenDataException { |
| if (data == null) { |
| return null; |
| } |
| MappedMXBeanType mt = getMappedType(t); |
| return mt.toOpenTypeData(data); |
| } |
| |
| // Return the mapped open type |
| OpenType getOpenType() { |
| return openType; |
| } |
| |
| boolean isBasicType() { |
| return isBasicType; |
| } |
| |
| // Return the type name of the mapped open type |
| // For primitive types, the type name is the same as the javaType |
| // but the mapped open type is the wrapper class |
| String getTypeName() { |
| return getMappedTypeClass().getName(); |
| } |
| |
| // Return the mapped open type |
| Class getMappedTypeClass() { |
| return mappedTypeClass; |
| } |
| |
| abstract Type getJavaType(); |
| |
| // return name of the class or the generic type |
| abstract String getName(); |
| |
| abstract Object toOpenTypeData(Object javaTypeData) |
| throws OpenDataException; |
| |
| abstract Object toJavaTypeData(Object openTypeData) |
| throws OpenDataException, InvalidObjectException; |
| |
| // Basic Types - Classes that do not require data conversion |
| // including primitive types and all SimpleType |
| // |
| // Mapped open type: SimpleType for corresponding basic type |
| // |
| // Data Mapping: |
| // T <-> T (no conversion) |
| // |
| static class BasicMXBeanType extends MappedMXBeanType { |
| final Class basicType; |
| BasicMXBeanType(Class c, OpenType openType) { |
| this.basicType = c; |
| this.openType = openType; |
| this.mappedTypeClass = c; |
| this.isBasicType = true; |
| } |
| |
| Type getJavaType() { |
| return basicType; |
| } |
| |
| String getName() { |
| return basicType.getName(); |
| } |
| |
| Object toOpenTypeData(Object data) throws OpenDataException { |
| return data; |
| } |
| |
| Object toJavaTypeData(Object data) |
| throws OpenDataException, InvalidObjectException { |
| |
| return data; |
| } |
| } |
| |
| |
| // Enum subclasses |
| // Mapped open type - String |
| // |
| // Data Mapping: |
| // Enum <-> enum's name |
| // |
| static class EnumMXBeanType extends MappedMXBeanType { |
| final Class enumClass; |
| EnumMXBeanType(Class c) { |
| this.enumClass = c; |
| this.openType = STRING; |
| this.mappedTypeClass = String.class; |
| } |
| |
| Type getJavaType() { |
| return enumClass; |
| } |
| |
| String getName() { |
| return enumClass.getName(); |
| } |
| |
| Object toOpenTypeData(Object data) throws OpenDataException { |
| return ((Enum) data).name(); |
| } |
| |
| Object toJavaTypeData(Object data) |
| throws OpenDataException, InvalidObjectException { |
| |
| try { |
| return Enum.valueOf(enumClass, (String) data); |
| } catch (IllegalArgumentException e) { |
| // missing enum constants |
| final InvalidObjectException ioe = |
| new InvalidObjectException("Enum constant named " + |
| (String) data + " is missing"); |
| ioe.initCause(e); |
| throw ioe; |
| } |
| } |
| } |
| |
| // Array E[] |
| // Mapped open type - Array with element of OpenType for E |
| // |
| // Data Mapping: |
| // E[] <-> openTypeData(E)[] |
| // |
| static class ArrayMXBeanType extends MappedMXBeanType { |
| final Class arrayClass; |
| protected MappedMXBeanType componentType; |
| protected MappedMXBeanType baseElementType; |
| |
| ArrayMXBeanType(Class c) throws OpenDataException { |
| this.arrayClass = c; |
| this.componentType = getMappedType(c.getComponentType()); |
| |
| StringBuilder className = new StringBuilder(); |
| Class et = c; |
| int dim; |
| for (dim = 0; et.isArray(); dim++) { |
| className.append('['); |
| et = et.getComponentType(); |
| } |
| baseElementType = getMappedType(et); |
| if (et.isPrimitive()) { |
| className = new StringBuilder(c.getName()); |
| } else { |
| className.append("L" + baseElementType.getTypeName() + ";"); |
| } |
| try { |
| mappedTypeClass = Class.forName(className.toString()); |
| } catch (ClassNotFoundException e) { |
| final OpenDataException ode = |
| new OpenDataException("Cannot obtain array class"); |
| ode.initCause(e); |
| throw ode; |
| } |
| |
| openType = new ArrayType(dim, baseElementType.getOpenType()); |
| } |
| |
| protected ArrayMXBeanType() { |
| arrayClass = null; |
| }; |
| |
| Type getJavaType() { |
| return arrayClass; |
| } |
| |
| String getName() { |
| return arrayClass.getName(); |
| } |
| |
| Object toOpenTypeData(Object data) throws OpenDataException { |
| // If the base element type is a basic type |
| // return the data as no conversion is needed. |
| // Primitive types are not converted to wrappers. |
| if (baseElementType.isBasicType()) { |
| return data; |
| } |
| |
| final Object[] array = (Object[]) data; |
| final Object[] openArray = (Object[]) |
| Array.newInstance(componentType.getMappedTypeClass(), |
| array.length); |
| int i = 0; |
| for (Object o : array) { |
| if (o == null) { |
| openArray[i] = null; |
| } else { |
| openArray[i] = componentType.toOpenTypeData(o); |
| } |
| i++; |
| } |
| return openArray; |
| } |
| |
| |
| Object toJavaTypeData(Object data) |
| throws OpenDataException, InvalidObjectException { |
| |
| // If the base element type is a basic type |
| // return the data as no conversion is needed. |
| if (baseElementType.isBasicType()) { |
| return data; |
| } |
| |
| final Object[] openArray = (Object[]) data; |
| final Object[] array = (Object[]) |
| Array.newInstance((Class) componentType.getJavaType(), |
| openArray.length); |
| int i = 0; |
| for (Object o : openArray) { |
| if (o == null) { |
| array[i] = null; |
| } else { |
| array[i] = componentType.toJavaTypeData(o); |
| } |
| i++; |
| } |
| return array; |
| } |
| |
| } |
| |
| static class GenericArrayMXBeanType extends ArrayMXBeanType { |
| final GenericArrayType gtype; |
| GenericArrayMXBeanType(GenericArrayType gat) throws OpenDataException { |
| this.gtype = gat; |
| this.componentType = getMappedType(gat.getGenericComponentType()); |
| |
| StringBuilder className = new StringBuilder(); |
| Type elementType = gat; |
| int dim; |
| for (dim = 0; elementType instanceof GenericArrayType; dim++) { |
| className.append('['); |
| GenericArrayType et = (GenericArrayType) elementType; |
| elementType = et.getGenericComponentType(); |
| } |
| baseElementType = getMappedType(elementType); |
| if (elementType instanceof Class && ((Class) elementType).isPrimitive()) { |
| className = new StringBuilder(gat.toString()); |
| } else { |
| className.append("L" + baseElementType.getTypeName() + ";"); |
| } |
| try { |
| mappedTypeClass = Class.forName(className.toString()); |
| } catch (ClassNotFoundException e) { |
| final OpenDataException ode = |
| new OpenDataException("Cannot obtain array class"); |
| ode.initCause(e); |
| throw ode; |
| } |
| |
| openType = new ArrayType(dim, baseElementType.getOpenType()); |
| } |
| |
| Type getJavaType() { |
| return gtype; |
| } |
| |
| String getName() { |
| return gtype.toString(); |
| } |
| } |
| |
| // List<E> |
| // Mapped open type - Array with element of OpenType for E |
| // |
| // Data Mapping: |
| // List<E> <-> openTypeData(E)[] |
| // |
| static class ListMXBeanType extends MappedMXBeanType { |
| final ParameterizedType javaType; |
| final MappedMXBeanType paramType; |
| final String typeName; |
| |
| ListMXBeanType(ParameterizedType pt) throws OpenDataException { |
| this.javaType = pt; |
| |
| final Type[] argTypes = pt.getActualTypeArguments(); |
| assert(argTypes.length == 1); |
| |
| if (!(argTypes[0] instanceof Class)) { |
| throw new OpenDataException("Element Type for " + pt + |
| " not supported"); |
| } |
| final Class et = (Class) argTypes[0]; |
| if (et.isArray()) { |
| throw new OpenDataException("Element Type for " + pt + |
| " not supported"); |
| } |
| paramType = getMappedType(et); |
| typeName = "List<" + paramType.getName() + ">"; |
| |
| try { |
| mappedTypeClass = Class.forName( |
| "[L" + paramType.getTypeName() + ";"); |
| } catch (ClassNotFoundException e) { |
| final OpenDataException ode = |
| new OpenDataException("Array class not found"); |
| ode.initCause(e); |
| throw ode; |
| } |
| openType = new ArrayType(1, paramType.getOpenType()); |
| } |
| |
| Type getJavaType() { |
| return javaType; |
| } |
| |
| String getName() { |
| return typeName; |
| } |
| |
| Object toOpenTypeData(Object data) throws OpenDataException { |
| final List<Object> list = (List<Object>) data; |
| |
| final Object[] openArray = (Object[]) |
| Array.newInstance(paramType.getMappedTypeClass(), |
| list.size()); |
| int i = 0; |
| for (Object o : list) { |
| openArray[i++] = paramType.toOpenTypeData(o); |
| } |
| return openArray; |
| } |
| |
| Object toJavaTypeData(Object data) |
| throws OpenDataException, InvalidObjectException { |
| |
| final Object[] openArray = (Object[]) data; |
| List<Object> result = new ArrayList<Object>(openArray.length); |
| for (Object o : openArray) { |
| result.add(paramType.toJavaTypeData(o)); |
| } |
| return result; |
| } |
| } |
| |
| private static final String KEY = "key"; |
| private static final String VALUE = "value"; |
| private static final String[] mapIndexNames = {KEY}; |
| private static final String[] mapItemNames = {KEY, VALUE}; |
| |
| // Map<K,V> |
| // Mapped open type - TabularType with row type: |
| // CompositeType: |
| // "key" of openDataType(K) |
| // "value" of openDataType(V) |
| // "key" is the index name |
| // |
| // Data Mapping: |
| // Map<K,V> <-> TabularData |
| // |
| static class MapMXBeanType extends MappedMXBeanType { |
| final ParameterizedType javaType; |
| final MappedMXBeanType keyType; |
| final MappedMXBeanType valueType; |
| final String typeName; |
| |
| MapMXBeanType(ParameterizedType pt) throws OpenDataException { |
| this.javaType = pt; |
| |
| final Type[] argTypes = pt.getActualTypeArguments(); |
| assert(argTypes.length == 2); |
| this.keyType = getMappedType(argTypes[0]); |
| this.valueType = getMappedType(argTypes[1]); |
| |
| |
| // FIXME: generate typeName for generic |
| typeName = "Map<" + keyType.getName() + "," + |
| valueType.getName() + ">"; |
| final OpenType[] mapItemTypes = new OpenType[] { |
| keyType.getOpenType(), |
| valueType.getOpenType(), |
| }; |
| final CompositeType rowType = |
| new CompositeType(typeName, |
| typeName, |
| mapItemNames, |
| mapItemNames, |
| mapItemTypes); |
| |
| openType = new TabularType(typeName, typeName, rowType, mapIndexNames); |
| mappedTypeClass = javax.management.openmbean.TabularData.class; |
| } |
| |
| Type getJavaType() { |
| return javaType; |
| } |
| |
| String getName() { |
| return typeName; |
| } |
| |
| Object toOpenTypeData(Object data) throws OpenDataException { |
| final Map<Object,Object> map = (Map<Object,Object>) data; |
| final TabularType tabularType = (TabularType) openType; |
| final TabularData table = new TabularDataSupport(tabularType); |
| final CompositeType rowType = tabularType.getRowType(); |
| |
| for (Map.Entry entry : map.entrySet()) { |
| final Object key = keyType.toOpenTypeData(entry.getKey()); |
| final Object value = valueType.toOpenTypeData(entry.getValue()); |
| final CompositeData row = |
| new CompositeDataSupport(rowType, |
| mapItemNames, |
| new Object[] {key, value}); |
| table.put(row); |
| } |
| return table; |
| } |
| |
| Object toJavaTypeData(Object data) |
| throws OpenDataException, InvalidObjectException { |
| |
| final TabularData td = (TabularData) data; |
| |
| Map<Object, Object> result = new HashMap<Object, Object>(); |
| for (CompositeData row : (Collection<CompositeData>) td.values()) { |
| Object key = keyType.toJavaTypeData(row.get(KEY)); |
| Object value = valueType.toJavaTypeData(row.get(VALUE)); |
| result.put(key, value); |
| } |
| return result; |
| } |
| } |
| |
| private static final Class<?> COMPOSITE_DATA_CLASS = |
| javax.management.openmbean.CompositeData.class; |
| |
| // Classes that have a static from method |
| // Mapped open type - CompositeData |
| // |
| // Data Mapping: |
| // Classes <-> CompositeData |
| // |
| // The name and type of items for a class are identified from |
| // the getter methods. For example, a class defines a method: |
| // |
| // public FooType getFoo(); |
| // |
| // The composite data view for this class will contain one |
| // item entry for a "foo" attribute and the item type is |
| // one of the open types defined in the OpenType class that |
| // can be determined in the following manner: |
| // o If FooType is a primitive type, the item type a wrapper |
| // class for the corresponding primitive type (such as |
| // Integer, Long, Boolean, etc). |
| // o If FooType is of type CompositeData or TabularData, |
| // the item type is FooType. |
| // o If FooType is an Enum, the item type is a String and |
| // the value is the name of the enum constant. |
| // o If FooType is a class or an interface other than the above, |
| // the item type is CompositeData. The same convention |
| // can be recursively applied to the FooType class when |
| // constructing the composite data for the "foo" attribute. |
| // o If FooType is an array, the item type is an array and |
| // its element type is determined as described above. |
| // |
| static class CompositeDataMXBeanType extends MappedMXBeanType { |
| final Class<?> javaClass; |
| final boolean isCompositeData; |
| Method fromMethod = null; |
| |
| CompositeDataMXBeanType(Class c) throws OpenDataException { |
| this.javaClass = c; |
| this.mappedTypeClass = COMPOSITE_DATA_CLASS; |
| |
| // check if a static from method exists |
| try { |
| fromMethod = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() { |
| public Method run() throws NoSuchMethodException { |
| return javaClass.getMethod("from", COMPOSITE_DATA_CLASS); |
| } |
| }); |
| } catch (PrivilegedActionException e) { |
| // ignore NoSuchMethodException since we allow classes |
| // that has no from method to be embeded in another class. |
| } |
| |
| if (COMPOSITE_DATA_CLASS.isAssignableFrom(c)) { |
| // c implements CompositeData - set openType to null |
| // defer generating the CompositeType |
| // until the object is constructed |
| this.isCompositeData = true; |
| this.openType = null; |
| } else { |
| this.isCompositeData = false; |
| |
| // Make a CompositeData containing all the getters |
| final Method[] methods = |
| AccessController.doPrivileged(new PrivilegedAction<Method[]>() { |
| public Method[] run() { |
| return javaClass.getMethods(); |
| } |
| }); |
| final List<String> names = new ArrayList<String>(); |
| final List<OpenType> types = new ArrayList<OpenType>(); |
| |
| /* 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 (int i = 0; i < methods.length; i++) { |
| final Method method = methods[i]; |
| final String name = method.getName(); |
| final Type type = method.getGenericReturnType(); |
| final String rest; |
| if (name.startsWith("get")) { |
| rest = name.substring(3); |
| } else if (name.startsWith("is") && |
| type instanceof Class && |
| ((Class) type) == boolean.class) { |
| rest = name.substring(2); |
| } else { |
| // ignore non-getter methods |
| continue; |
| } |
| |
| if (rest.equals("") || |
| method.getParameterTypes().length > 0 || |
| type == void.class || |
| rest.equals("Class")) { |
| |
| // ignore non-getter methods |
| continue; |
| } |
| names.add(decapitalize(rest)); |
| types.add(toOpenType(type)); |
| } |
| |
| final String[] nameArray = names.toArray(new String[0]); |
| openType = new CompositeType(c.getName(), |
| c.getName(), |
| nameArray, // field names |
| nameArray, // field descriptions |
| types.toArray(new OpenType[0])); |
| } |
| } |
| |
| Type getJavaType() { |
| return javaClass; |
| } |
| |
| String getName() { |
| return javaClass.getName(); |
| } |
| |
| Object toOpenTypeData(Object data) throws OpenDataException { |
| if (data instanceof MemoryUsage) { |
| return MemoryUsageCompositeData.toCompositeData((MemoryUsage) data); |
| } |
| |
| if (data instanceof ThreadInfo) { |
| return ThreadInfoCompositeData.toCompositeData((ThreadInfo) data); |
| } |
| |
| if (data instanceof LockInfo) { |
| if (data instanceof java.lang.management.MonitorInfo) { |
| return MonitorInfoCompositeData.toCompositeData((MonitorInfo) data); |
| } |
| return LockDataConverter.toLockInfoCompositeData((LockInfo) data); |
| } |
| |
| if (data instanceof MemoryNotificationInfo) { |
| return MemoryNotifInfoCompositeData. |
| toCompositeData((MemoryNotificationInfo) data); |
| } |
| |
| if (data instanceof VMOption) { |
| return VMOptionCompositeData.toCompositeData((VMOption) data); |
| } |
| |
| if (isCompositeData) { |
| // Classes that implement CompositeData |
| // |
| // construct a new CompositeDataSupport object |
| // so that no other classes are sent over the wire |
| CompositeData cd = (CompositeData) data; |
| CompositeType ct = cd.getCompositeType(); |
| String[] itemNames = (String[]) ct.keySet().toArray(new String[0]); |
| Object[] itemValues = cd.getAll(itemNames); |
| return new CompositeDataSupport(ct, itemNames, itemValues); |
| } |
| |
| throw new OpenDataException(javaClass.getName() + |
| " is not supported for platform MXBeans"); |
| } |
| |
| Object toJavaTypeData(Object data) |
| throws OpenDataException, InvalidObjectException { |
| |
| if (fromMethod == null) { |
| throw new AssertionError("Does not support data conversion"); |
| } |
| |
| try { |
| return fromMethod.invoke(null, data); |
| } catch (IllegalAccessException e) { |
| // should never reach here |
| throw new AssertionError(e); |
| } catch (InvocationTargetException e) { |
| final OpenDataException ode = |
| new OpenDataException("Failed to invoke " + |
| fromMethod.getName() + " to convert CompositeData " + |
| " to " + javaClass.getName()); |
| ode.initCause(e); |
| throw ode; |
| } |
| } |
| } |
| |
| private static class InProgress extends OpenType { |
| private static final String description = |
| "Marker to detect recursive type use -- internal use only!"; |
| |
| InProgress() throws OpenDataException { |
| super("java.lang.String", "java.lang.String", description); |
| } |
| |
| public String toString() { |
| return description; |
| } |
| |
| public int hashCode() { |
| return 0; |
| } |
| |
| public boolean equals(Object o) { |
| return false; |
| } |
| |
| public boolean isValue(Object o) { |
| return false; |
| } |
| private static final long serialVersionUID = -3413063475064374490L; |
| } |
| private static final OpenType inProgress; |
| static { |
| OpenType t; |
| try { |
| t = new InProgress(); |
| } catch (OpenDataException e) { |
| // Should not reach here |
| throw new AssertionError(e); |
| } |
| inProgress = t; |
| } |
| |
| private static final OpenType[] simpleTypes = { |
| BIGDECIMAL, BIGINTEGER, BOOLEAN, BYTE, CHARACTER, DATE, |
| DOUBLE, FLOAT, INTEGER, LONG, OBJECTNAME, SHORT, STRING, |
| VOID, |
| }; |
| static { |
| try { |
| for (int i = 0; i < simpleTypes.length; i++) { |
| final OpenType t = simpleTypes[i]; |
| Class c; |
| try { |
| c = Class.forName(t.getClassName(), false, |
| String.class.getClassLoader()); |
| MappedMXBeanType.newBasicType(c, t); |
| } catch (ClassNotFoundException e) { |
| // the classes that these predefined types declare |
| // must exist! |
| throw new AssertionError(e); |
| } catch (OpenDataException e) { |
| throw new AssertionError(e); |
| } |
| |
| if (c.getName().startsWith("java.lang.")) { |
| try { |
| final Field typeField = c.getField("TYPE"); |
| final Class primitiveType = (Class) typeField.get(null); |
| MappedMXBeanType.newBasicType(primitiveType, t); |
| } catch (NoSuchFieldException e) { |
| // OK: must not be a primitive wrapper |
| } catch (IllegalAccessException e) { |
| // Should not reach here |
| throw new AssertionError(e); |
| } |
| } |
| } |
| } catch (OpenDataException e) { |
| throw new AssertionError(e); |
| } |
| } |
| |
| /** |
| * Utility method to take a string and convert it to normal Java variable |
| * name capitalization. This normally means converting the first |
| * character from upper case to lower case, but in the (unusual) special |
| * case when there is more than one character and both the first and |
| * second characters are upper case, we leave it alone. |
| * <p> |
| * Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays |
| * as "URL". |
| * |
| * @param name The string to be decapitalized. |
| * @return The decapitalized version of the string. |
| */ |
| private static String decapitalize(String name) { |
| if (name == null || name.length() == 0) { |
| return name; |
| } |
| if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && |
| Character.isUpperCase(name.charAt(0))){ |
| return name; |
| } |
| char chars[] = name.toCharArray(); |
| chars[0] = Character.toLowerCase(chars[0]); |
| return new String(chars); |
| } |
| |
| } |