jdk/src/java.management/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java
changeset 30906 1b67cbb0adce
parent 30655 d83f50188ca9
child 33315 d2a313368ccb
equal deleted inserted replaced
30806:6e9d62b1dbc3 30906:1b67cbb0adce
     1 /*
     1 /*
     2  * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     7  * published by the Free Software Foundation.  Oracle designates this
    31 import static javax.management.openmbean.SimpleType.*;
    31 import static javax.management.openmbean.SimpleType.*;
    32 
    32 
    33 import com.sun.jmx.remote.util.EnvHelp;
    33 import com.sun.jmx.remote.util.EnvHelp;
    34 
    34 
    35 import java.io.InvalidObjectException;
    35 import java.io.InvalidObjectException;
    36 import java.lang.annotation.Annotation;
       
    37 import java.lang.annotation.ElementType;
    36 import java.lang.annotation.ElementType;
    38 import java.lang.ref.WeakReference;
    37 import java.lang.ref.WeakReference;
    39 import java.lang.reflect.Array;
    38 import java.lang.reflect.Array;
    40 import java.lang.reflect.Constructor;
    39 import java.lang.reflect.Constructor;
    41 import java.lang.reflect.Field;
    40 import java.lang.reflect.Field;
    42 import java.lang.reflect.GenericArrayType;
    41 import java.lang.reflect.GenericArrayType;
    43 import java.lang.reflect.InvocationTargetException;
       
    44 import java.lang.reflect.Method;
    42 import java.lang.reflect.Method;
    45 import java.lang.reflect.Modifier;
    43 import java.lang.reflect.Modifier;
    46 import java.lang.reflect.ParameterizedType;
    44 import java.lang.reflect.ParameterizedType;
    47 import java.lang.reflect.Proxy;
    45 import java.lang.reflect.Proxy;
    48 import java.lang.reflect.Type;
    46 import java.lang.reflect.Type;
  1136     /** Builder for when the target class has a constructor that is
  1134     /** Builder for when the target class has a constructor that is
  1137         annotated with @ConstructorProperties so we can see the correspondence
  1135         annotated with @ConstructorProperties so we can see the correspondence
  1138         to getters.  */
  1136         to getters.  */
  1139     private static final class CompositeBuilderViaConstructor
  1137     private static final class CompositeBuilderViaConstructor
  1140             extends CompositeBuilder {
  1138             extends CompositeBuilder {
  1141         static class AnnotationHelper {
       
  1142             private static Class<? extends Annotation> constructorPropertiesClass;
       
  1143             private static Method valueMethod;
       
  1144             static {
       
  1145                 findConstructorPropertiesClass();
       
  1146             }
       
  1147 
       
  1148             @SuppressWarnings("unchecked")
       
  1149             private static void findConstructorPropertiesClass() {
       
  1150                 try {
       
  1151                     constructorPropertiesClass = (Class<? extends Annotation>)
       
  1152                         Class.forName("java.beans.ConstructorProperties", false,
       
  1153                                       DefaultMXBeanMappingFactory.class.getClassLoader());
       
  1154                     valueMethod = constructorPropertiesClass.getMethod("value");
       
  1155                 } catch (ClassNotFoundException cnf) {
       
  1156                     // java.beans not present
       
  1157                 } catch (NoSuchMethodException e) {
       
  1158                     // should not reach here
       
  1159                     throw new InternalError(e);
       
  1160                 }
       
  1161             }
       
  1162 
       
  1163             static boolean isAvailable() {
       
  1164                 return constructorPropertiesClass != null;
       
  1165             }
       
  1166 
       
  1167             static String[] getPropertyNames(Constructor<?> constr) {
       
  1168                 if (!isAvailable())
       
  1169                     return null;
       
  1170 
       
  1171                 Annotation a = constr.getAnnotation(constructorPropertiesClass);
       
  1172                 if (a == null) return null;
       
  1173 
       
  1174                 try {
       
  1175                     return (String[]) valueMethod.invoke(a);
       
  1176                 } catch (InvocationTargetException e) {
       
  1177                     throw new InternalError(e);
       
  1178                 } catch (IllegalAccessException e) {
       
  1179                     throw new InternalError(e);
       
  1180                 }
       
  1181             }
       
  1182         }
       
  1183 
  1139 
  1184         CompositeBuilderViaConstructor(Class<?> targetClass, String[] itemNames) {
  1140         CompositeBuilderViaConstructor(Class<?> targetClass, String[] itemNames) {
  1185             super(targetClass, itemNames);
  1141             super(targetClass, itemNames);
  1186         }
  1142         }
  1187 
  1143 
  1188         String applicable(Method[] getters) throws InvalidObjectException {
  1144         String applicable(Method[] getters) throws InvalidObjectException {
  1189             if (!AnnotationHelper.isAvailable())
  1145             if (!JavaBeansAccessor.isAvailable())
  1190                 return "@ConstructorProperties annotation not available";
  1146                 return "@ConstructorProperties annotation not available";
  1191 
  1147 
  1192             Class<?> targetClass = getTargetClass();
  1148             Class<?> targetClass = getTargetClass();
  1193             Constructor<?>[] constrs = targetClass.getConstructors();
  1149             Constructor<?>[] constrs = targetClass.getConstructors();
  1194 
  1150 
  1195             // Applicable if and only if there are any annotated constructors
  1151             // Applicable if and only if there are any annotated constructors
  1196             List<Constructor<?>> annotatedConstrList = newList();
  1152             List<Constructor<?>> annotatedConstrList = newList();
  1197             for (Constructor<?> constr : constrs) {
  1153             for (Constructor<?> constr : constrs) {
  1198                 if (Modifier.isPublic(constr.getModifiers())
  1154                 if (Modifier.isPublic(constr.getModifiers())
  1199                         && AnnotationHelper.getPropertyNames(constr) != null)
  1155                         && JavaBeansAccessor.getConstructorPropertiesValue(constr) != null)
  1200                     annotatedConstrList.add(constr);
  1156                     annotatedConstrList.add(constr);
  1201             }
  1157             }
  1202 
  1158 
  1203             if (annotatedConstrList.isEmpty())
  1159             if (annotatedConstrList.isEmpty())
  1204                 return "no constructor has @ConstructorProperties annotation";
  1160                 return "no constructor has @ConstructorProperties annotation";
  1223             // element is -1, that item isn't given to the constructor.
  1179             // element is -1, that item isn't given to the constructor.
  1224             // Also remember the set of properties in that constructor
  1180             // Also remember the set of properties in that constructor
  1225             // so we can test unambiguity.
  1181             // so we can test unambiguity.
  1226             Set<BitSet> getterIndexSets = newSet();
  1182             Set<BitSet> getterIndexSets = newSet();
  1227             for (Constructor<?> constr : annotatedConstrList) {
  1183             for (Constructor<?> constr : annotatedConstrList) {
  1228                 String[] propertyNames = AnnotationHelper.getPropertyNames(constr);
  1184                 String[] propertyNames = JavaBeansAccessor.getConstructorPropertiesValue(constr);
  1229 
  1185 
  1230                 Type[] paramTypes = constr.getGenericParameterTypes();
  1186                 Type[] paramTypes = constr.getGenericParameterTypes();
  1231                 if (paramTypes.length != propertyNames.length) {
  1187                 if (paramTypes.length != propertyNames.length) {
  1232                     final String msg =
  1188                     final String msg =
  1233                         "Number of constructor params does not match " +
  1189                         "Number of constructor params does not match " +