jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java
author emcmanus
Wed, 21 Oct 2009 17:33:18 +0200
changeset 4156 acaa49a2768a
parent 1512 0f8eb7ad4ef5
child 5506 202f599c92aa
permissions -rw-r--r--
6851617: Remove JSR 255 (JMX API 2.0) from JDK 7 Summary: See http://weblogs.java.net/blog/2009/06/16/jsr-255-jmx-api-20-postponed Reviewed-by: dfuchs
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
715
f16baef3a20e 6719955: Update copyright year
xdono
parents: 687
diff changeset
     2
 * Copyright 2005-2008 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package com.sun.jmx.mbeanserver;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import static com.sun.jmx.mbeanserver.Util.*;
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
    29
import static com.sun.jmx.mbeanserver.MXBeanIntrospector.typeName;
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
    30
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import static javax.management.openmbean.SimpleType.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import com.sun.jmx.remote.util.EnvHelp;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.beans.ConstructorProperties;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.io.InvalidObjectException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import java.lang.annotation.ElementType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.lang.ref.WeakReference;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import java.lang.reflect.Array;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.lang.reflect.Constructor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.lang.reflect.Field;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.lang.reflect.GenericArrayType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.lang.reflect.Method;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import java.lang.reflect.Modifier;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import java.lang.reflect.ParameterizedType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import java.lang.reflect.Proxy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import java.lang.reflect.Type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
import java.util.ArrayList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
import java.util.Arrays;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
import java.util.BitSet;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
import java.util.Collection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
import java.util.Comparator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
import java.util.HashSet;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
import java.util.List;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
import java.util.Map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
import java.util.Set;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
import java.util.SortedMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
import java.util.SortedSet;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
import java.util.TreeSet;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
import java.util.WeakHashMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
import javax.management.JMX;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
import javax.management.ObjectName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
import javax.management.openmbean.ArrayType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
import javax.management.openmbean.CompositeData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
import javax.management.openmbean.CompositeDataInvocationHandler;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
import javax.management.openmbean.CompositeDataSupport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
import javax.management.openmbean.CompositeDataView;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
import javax.management.openmbean.CompositeType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
import javax.management.openmbean.OpenDataException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
import javax.management.openmbean.OpenType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
import javax.management.openmbean.SimpleType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
import javax.management.openmbean.TabularData;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
import javax.management.openmbean.TabularDataSupport;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
import javax.management.openmbean.TabularType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
/**
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    78
 *   <p>A converter between Java types and the limited set of classes
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    79
 *   defined by Open MBeans.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    80
 *
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    81
 *   <p>A Java type is an instance of java.lang.reflect.Type.  For our
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    82
 *   purposes, it is either a Class, such as String.class or int.class;
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    83
 *   or a ParameterizedType, such as List<String> or Map<Integer,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    84
 *   String[]>.  On J2SE 1.4 and earlier, it can only be a Class.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    85
 *
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    86
 *   <p>Each Type is associated with an DefaultMXBeanMappingFactory.  The
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    87
 *   DefaultMXBeanMappingFactory defines an OpenType corresponding to the Type, plus a
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    88
 *   Java class corresponding to the OpenType.  For example:</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    89
 *
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    90
 *   <pre>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    91
 *   Type                     Open class     OpenType
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    92
 *   ----                     ----------     --------
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    93
 *   Integer                Integer        SimpleType.INTEGER
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    94
 *   int                            int            SimpleType.INTEGER
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    95
 *   Integer[]              Integer[]      ArrayType(1, SimpleType.INTEGER)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    96
 *   int[]                  Integer[]      ArrayType(SimpleType.INTEGER, true)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    97
 *   String[][]             String[][]     ArrayType(2, SimpleType.STRING)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    98
 *   List<String>                   String[]       ArrayType(1, SimpleType.STRING)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
    99
 *   ThreadState (an Enum)    String         SimpleType.STRING
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   100
 *   Map<Integer, String[]>   TabularData          TabularType(
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   101
 *                                           CompositeType(
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   102
 *                                             {"key", SimpleType.INTEGER},
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   103
 *                                             {"value",
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   104
 *                                               ArrayType(1,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   105
 *                                                SimpleType.STRING)}),
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   106
 *                                           indexNames={"key"})
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   107
 *   </pre>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   108
 *
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   109
 *   <p>Apart from simple types, arrays, and collections, Java types are
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   110
 *   converted through introspection into CompositeType.  The Java type
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   111
 *   must have at least one getter (method such as "int getSize()" or
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   112
 *   "boolean isBig()"), and we must be able to deduce how to
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   113
 *   reconstruct an instance of the Java class from the values of the
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   114
 *   getters using one of various heuristics.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   115
 *
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   116
 * @since 1.6
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   117
 */
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   118
public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   119
    static abstract class NonNullMXBeanMapping extends MXBeanMapping {
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   120
        NonNullMXBeanMapping(Type javaType, OpenType<?> openType) {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   121
            super(javaType, openType);
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   122
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   124
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   125
        public final Object fromOpenValue(Object openValue)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   126
        throws InvalidObjectException {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   127
            if (openValue == null)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   128
                return null;
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   129
            else
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   130
                return fromNonNullOpenValue(openValue);
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   131
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   133
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   134
        public final Object toOpenValue(Object javaValue) throws OpenDataException {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   135
            if (javaValue == null)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   136
                return null;
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   137
            else
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   138
                return toNonNullOpenValue(javaValue);
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   139
        }
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   140
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   141
        abstract Object fromNonNullOpenValue(Object openValue)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   142
        throws InvalidObjectException;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   144
        abstract Object toNonNullOpenValue(Object javaValue)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   145
        throws OpenDataException;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   147
        /**
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   148
         * <p>True if and only if this MXBeanMapping's toOpenValue and
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   149
         * fromOpenValue methods are the identity function.</p>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   150
         */
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   151
        boolean isIdentity() {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   152
            return false;
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   153
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   156
    static boolean isIdentity(MXBeanMapping mapping) {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   157
        return (mapping instanceof NonNullMXBeanMapping &&
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   158
                ((NonNullMXBeanMapping) mapping).isIdentity());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   161
    private static final class Mappings
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   162
        extends WeakHashMap<Type, WeakReference<MXBeanMapping>> {}
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
4156
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   164
    private static final Mappings mappings = new Mappings();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
4156
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   166
    /** Following List simply serves to keep a reference to predefined
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   167
        MXBeanMappings so they don't get garbage collected. */
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   168
    private static final List<MXBeanMapping> permanentMappings = newList();
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   169
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   170
    private static synchronized MXBeanMapping getMapping(Type type) {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   171
        WeakReference<MXBeanMapping> wr = mappings.get(type);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        return (wr == null) ? null : wr.get();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
4156
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   175
    private static synchronized void putMapping(Type type, MXBeanMapping mapping) {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   176
        WeakReference<MXBeanMapping> wr =
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   177
            new WeakReference<MXBeanMapping>(mapping);
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   178
        mappings.put(type, wr);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
4156
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   181
    private static synchronized void putPermanentMapping(
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   182
            Type type, MXBeanMapping mapping) {
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   183
        putMapping(type, mapping);
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   184
        permanentMappings.add(mapping);
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   185
    }
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   186
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
        /* Set up the mappings for Java types that map to SimpleType.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   190
        final OpenType<?>[] simpleTypes = {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            BIGDECIMAL, BIGINTEGER, BOOLEAN, BYTE, CHARACTER, DATE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            DOUBLE, FLOAT, INTEGER, LONG, OBJECTNAME, SHORT, STRING,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            VOID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        for (int i = 0; i < simpleTypes.length; i++) {
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   197
            final OpenType<?> t = simpleTypes[i];
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   198
            Class<?> c;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                c = Class.forName(t.getClassName(), false,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
                                  ObjectName.class.getClassLoader());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            } catch (ClassNotFoundException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                // the classes that these predefined types declare must exist!
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                throw new Error(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            }
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   206
            final MXBeanMapping mapping = new IdentityMapping(c, t);
4156
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   207
            putPermanentMapping(c, mapping);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
            if (c.getName().startsWith("java.lang.")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                    final Field typeField = c.getField("TYPE");
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   212
                    final Class<?> primitiveType = (Class<?>) typeField.get(null);
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   213
                    final MXBeanMapping primitiveMapping =
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   214
                        new IdentityMapping(primitiveType, t);
4156
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   215
                    putPermanentMapping(primitiveType, primitiveMapping);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                    if (primitiveType != void.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                        final Class<?> primitiveArrayType =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
                            Array.newInstance(primitiveType, 0).getClass();
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   219
                        final OpenType<?> primitiveArrayOpenType =
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                            ArrayType.getPrimitiveArrayType(primitiveArrayType);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   221
                        final MXBeanMapping primitiveArrayMapping =
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   222
                            new IdentityMapping(primitiveArrayType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   223
                                                primitiveArrayOpenType);
4156
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   224
                        putPermanentMapping(primitiveArrayType,
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   225
                                            primitiveArrayMapping);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                } catch (NoSuchFieldException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
                    // OK: must not be a primitive wrapper
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                } catch (IllegalAccessException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                    // Should not reach here
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                    assert(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
    /** Get the converter for the given Java type, creating it if necessary. */
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   238
    @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   239
    public synchronized MXBeanMapping mappingForType(Type objType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   240
                                                     MXBeanMappingFactory factory)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            throws OpenDataException {
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   242
        if (inProgress.containsKey(objType)) {
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   243
            throw new OpenDataException(
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   244
                    "Recursive data structure, including " + typeName(objType));
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   245
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   247
        MXBeanMapping mapping;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
4156
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   249
        mapping = getMapping(objType);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   250
        if (mapping != null)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   251
            return mapping;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        inProgress.put(objType, objType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        try {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   255
            mapping = makeMapping(objType, factory);
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   256
        } catch (OpenDataException e) {
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   257
            throw openDataException("Cannot convert type: " + typeName(objType), e);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            inProgress.remove(objType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
4156
acaa49a2768a 6851617: Remove JSR 255 (JMX API 2.0) from JDK 7
emcmanus
parents: 1512
diff changeset
   262
        putMapping(objType, mapping);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   263
        return mapping;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   266
    private MXBeanMapping makeMapping(Type objType, MXBeanMappingFactory factory)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   267
    throws OpenDataException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        /* It's not yet worth formalizing these tests by having for example
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
           an array of factory classes, each of which says whether it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
           recognizes the Type (Chain of Responsibility pattern).  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        if (objType instanceof GenericArrayType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            Type componentType =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                ((GenericArrayType) objType).getGenericComponentType();
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   275
            return makeArrayOrCollectionMapping(objType, componentType, factory);
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   276
        } else if (objType instanceof Class<?>) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            Class<?> objClass = (Class<?>) objType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            if (objClass.isEnum()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                // Huge hack to avoid compiler warnings here.  The ElementType
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                // parameter is ignored but allows us to obtain a type variable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                // T that matches <T extends Enum<T>>.
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   282
                return makeEnumMapping((Class<?>) objClass, ElementType.class);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            } else if (objClass.isArray()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                Type componentType = objClass.getComponentType();
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   285
                return makeArrayOrCollectionMapping(objClass, componentType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   286
                        factory);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            } else if (JMX.isMXBeanInterface(objClass)) {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   288
                return makeMXBeanRefMapping(objClass);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            } else {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   290
                return makeCompositeMapping(objClass, factory);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        } else if (objType instanceof ParameterizedType) {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   293
            return makeParameterizedTypeMapping((ParameterizedType) objType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   294
                                                factory);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        } else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
            throw new OpenDataException("Cannot map type: " + objType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   299
    private static <T extends Enum<T>> MXBeanMapping
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   300
            makeEnumMapping(Class<?> enumClass, Class<T> fake) {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   301
        return new EnumMapping<T>(Util.<Class<T>>cast(enumClass));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    /* Make the converter for an array type, or a collection such as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
     * List<String> or Set<Integer>.  We never see one-dimensional
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
     * primitive arrays (e.g. int[]) here because they use the identity
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
     * converter and are registered as such in the static initializer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     */
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   309
    private MXBeanMapping
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   310
        makeArrayOrCollectionMapping(Type collectionType, Type elementType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   311
                                     MXBeanMappingFactory factory)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            throws OpenDataException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   314
        final MXBeanMapping elementMapping = factory.mappingForType(elementType, factory);
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   315
        final OpenType<?> elementOpenType = elementMapping.getOpenType();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
        final ArrayType<?> openType = ArrayType.getArrayType(elementOpenType);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   317
        final Class<?> elementOpenClass = elementMapping.getOpenClass();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        final Class<?> openArrayClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        final String openArrayClassName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        if (elementOpenClass.isArray())
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            openArrayClassName = "[" + elementOpenClass.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            openArrayClassName = "[L" + elementOpenClass.getName() + ";";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            openArrayClass = Class.forName(openArrayClassName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        } catch (ClassNotFoundException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
            throw openDataException("Cannot obtain array class", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
        if (collectionType instanceof ParameterizedType) {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   332
            return new CollectionMapping(collectionType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   333
                                         openType, openArrayClass,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   334
                                         elementMapping);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        } else {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   336
            if (isIdentity(elementMapping)) {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   337
                return new IdentityMapping(collectionType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   338
                                           openType);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            } else {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   340
                return new ArrayMapping(collectionType,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                                          openType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                                          openArrayClass,
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   343
                                          elementMapping);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
    private static final String[] keyArray = {"key"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    private static final String[] keyValueArray = {"key", "value"};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   351
    private MXBeanMapping
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   352
        makeTabularMapping(Type objType, boolean sortedMap,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   353
                           Type keyType, Type valueType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   354
                           MXBeanMappingFactory factory)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            throws OpenDataException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   357
        final String objTypeName = typeName(objType);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   358
        final MXBeanMapping keyMapping = factory.mappingForType(keyType, factory);
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   359
        final MXBeanMapping valueMapping = factory.mappingForType(valueType, factory);
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   360
        final OpenType<?> keyOpenType = keyMapping.getOpenType();
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   361
        final OpenType<?> valueOpenType = valueMapping.getOpenType();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        final CompositeType rowType =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            new CompositeType(objTypeName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                              objTypeName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                              keyValueArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                              keyValueArray,
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   367
                              new OpenType<?>[] {keyOpenType, valueOpenType});
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        final TabularType tabularType =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
            new TabularType(objTypeName, objTypeName, rowType, keyArray);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   370
        return new TabularMapping(objType, sortedMap, tabularType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   371
                                    keyMapping, valueMapping);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    /* We know how to translate List<E>, Set<E>, SortedSet<E>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
       Map<K,V>, SortedMap<K,V>, and that's it.  We don't accept
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
       subtypes of those because we wouldn't know how to deserialize
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
       them.  We don't accept Queue<E> because it is unlikely people
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
       would use that as a parameter or return type in an MBean.  */
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   379
    private MXBeanMapping
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   380
            makeParameterizedTypeMapping(ParameterizedType objType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   381
                                         MXBeanMappingFactory factory)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   382
            throws OpenDataException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
        final Type rawType = objType.getRawType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   386
        if (rawType instanceof Class<?>) {
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   387
            Class<?> c = (Class<?>) rawType;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            if (c == List.class || c == Set.class || c == SortedSet.class) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                Type[] actuals = objType.getActualTypeArguments();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                assert(actuals.length == 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
                if (c == SortedSet.class)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                    mustBeComparable(c, actuals[0]);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   393
                return makeArrayOrCollectionMapping(objType, actuals[0], factory);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                boolean sortedMap = (c == SortedMap.class);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                if (c == Map.class || sortedMap) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
                    Type[] actuals = objType.getActualTypeArguments();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                    assert(actuals.length == 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
                    if (sortedMap)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
                        mustBeComparable(c, actuals[0]);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   401
                    return makeTabularMapping(objType, sortedMap,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   402
                            actuals[0], actuals[1], factory);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        throw new OpenDataException("Cannot convert type: " + objType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   409
    private static MXBeanMapping makeMXBeanRefMapping(Type t)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            throws OpenDataException {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   411
        return new MXBeanRefMapping(t);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   414
    private MXBeanMapping makeCompositeMapping(Class<?> c,
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   415
                                               MXBeanMappingFactory factory)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
            throws OpenDataException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        // For historical reasons GcInfo implements CompositeData but we
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        // shouldn't count its CompositeData.getCompositeType() field as
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        // an item in the computed CompositeType.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        final boolean gcInfoHack =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            (c.getName().equals("com.sun.management.GcInfo") &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                c.getClassLoader() == null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        final List<Method> methods =
287
bff5501b2a02 6610917: Define a generic NotificationFilter
emcmanus
parents: 268
diff changeset
   426
                MBeanAnalyzer.eliminateCovariantMethods(Arrays.asList(c.getMethods()));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        final SortedMap<String,Method> getterMap = newSortedMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        /* Select public methods that look like "T getX()" or "boolean
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
           isX()", where T is not void and X is not the empty
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
           string.  Exclude "Class getClass()" inherited from Object.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        for (Method method : methods) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            final String propertyName = propertyName(method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            if (propertyName == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            if (gcInfoHack && propertyName.equals("CompositeType"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            Method old =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
                getterMap.put(decapitalize(propertyName),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                            method);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            if (old != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                    "Class " + c.getName() + " has method name clash: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                    old.getName() + ", " + method.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                throw new OpenDataException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        final int nitems = getterMap.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        if (nitems == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            throw new OpenDataException("Can't map " + c.getName() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                                        " to an open data type");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        final Method[] getters = new Method[nitems];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        final String[] itemNames = new String[nitems];
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   460
        final OpenType<?>[] openTypes = new OpenType<?>[nitems];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
        int i = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        for (Map.Entry<String,Method> entry : getterMap.entrySet()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
            itemNames[i] = entry.getKey();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            final Method getter = entry.getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
            getters[i] = getter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
            final Type retType = getter.getGenericReturnType();
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   467
            openTypes[i] = factory.mappingForType(retType, factory).getOpenType();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
            i++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        CompositeType compositeType =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
            new CompositeType(c.getName(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                              c.getName(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                              itemNames, // field names
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                              itemNames, // field descriptions
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                              openTypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   478
        return new CompositeMapping(c,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   479
                                    compositeType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   480
                                    itemNames,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   481
                                    getters,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   482
                                    factory);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
    /* Converter for classes where the open data is identical to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
       original data.  This is true for any of the SimpleType types,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
       and for an any-dimension array of those.  It is also true for
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   488
       primitive types as of JMX 1.3, since an int[]
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
       can be directly represented by an ArrayType, and an int needs no mapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
       because reflection takes care of it.  */
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   491
    private static final class IdentityMapping extends NonNullMXBeanMapping {
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   492
        IdentityMapping(Type targetType, OpenType<?> openType) {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   493
            super(targetType, openType);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        boolean isIdentity() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   500
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   501
        Object fromNonNullOpenValue(Object openValue)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   502
        throws InvalidObjectException {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   503
            return openValue;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   506
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   507
        Object toNonNullOpenValue(Object javaValue) throws OpenDataException {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   508
            return javaValue;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   512
    private static final class EnumMapping<T extends Enum<T>>
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   513
            extends NonNullMXBeanMapping {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   515
        EnumMapping(Class<T> enumClass) {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   516
            super(enumClass, SimpleType.STRING);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            this.enumClass = enumClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   520
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   521
        final Object toNonNullOpenValue(Object value) {
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   522
            return ((Enum<?>) value).name();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   525
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   526
        final T fromNonNullOpenValue(Object value)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                throws InvalidObjectException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                return Enum.valueOf(enumClass, (String) value);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
                throw invalidObjectException("Cannot convert to enum: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                                             value, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
        private final Class<T> enumClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   539
    private static final class ArrayMapping extends NonNullMXBeanMapping {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   540
        ArrayMapping(Type targetType,
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   541
                     ArrayType<?> openArrayType, Class<?> openArrayClass,
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   542
                     MXBeanMapping elementMapping) {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   543
            super(targetType, openArrayType);
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   544
            this.elementMapping = elementMapping;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   547
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   548
        final Object toNonNullOpenValue(Object value)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                throws OpenDataException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            Object[] valueArray = (Object[]) value;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            final int len = valueArray.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            final Object[] openArray = (Object[])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                Array.newInstance(getOpenClass().getComponentType(), len);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   554
            for (int i = 0; i < len; i++)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   555
                openArray[i] = elementMapping.toOpenValue(valueArray[i]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
            return openArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   559
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   560
        final Object fromNonNullOpenValue(Object openValue)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                throws InvalidObjectException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
            final Object[] openArray = (Object[]) openValue;
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   563
            final Type javaType = getJavaType();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
            final Object[] valueArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
            final Type componentType;
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   566
            if (javaType instanceof GenericArrayType) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                componentType =
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   568
                    ((GenericArrayType) javaType).getGenericComponentType();
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   569
            } else if (javaType instanceof Class<?> &&
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   570
                       ((Class<?>) javaType).isArray()) {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   571
                componentType = ((Class<?>) javaType).getComponentType();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
                throw new IllegalArgumentException("Not an array: " +
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   574
                                                   javaType);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
            valueArray = (Object[]) Array.newInstance((Class<?>) componentType,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                                                      openArray.length);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   578
            for (int i = 0; i < openArray.length; i++)
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   579
                valueArray[i] = elementMapping.fromOpenValue(openArray[i]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            return valueArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   583
        public void checkReconstructible() throws InvalidObjectException {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   584
            elementMapping.checkReconstructible();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   587
        /**
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   588
         * DefaultMXBeanMappingFactory for the elements of this array.  If this is an
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   589
         *          array of arrays, the converter converts the second-level arrays,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   590
         *          not the deepest elements.
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   591
         */
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   592
        private final MXBeanMapping elementMapping;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   595
    private static final class CollectionMapping extends NonNullMXBeanMapping {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   596
        CollectionMapping(Type targetType,
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   597
                          ArrayType<?> openArrayType,
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   598
                          Class<?> openArrayClass,
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   599
                          MXBeanMapping elementMapping) {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   600
            super(targetType, openArrayType);
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   601
            this.elementMapping = elementMapping;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
            /* Determine the concrete class to be used when converting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
               back to this Java type.  We convert all Lists to ArrayList
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
               and all Sets to TreeSet.  (TreeSet because it is a SortedSet,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
               so works for both Set and SortedSet.)  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            Type raw = ((ParameterizedType) targetType).getRawType();
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   608
            Class<?> c = (Class<?>) raw;
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   609
            final Class<?> collC;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
            if (c == List.class)
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   611
                collC = ArrayList.class;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            else if (c == Set.class)
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   613
                collC = HashSet.class;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
            else if (c == SortedSet.class)
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   615
                collC = TreeSet.class;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
            else { // can't happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
                assert(false);
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   618
                collC = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
            }
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   620
            collectionClass = Util.cast(collC);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   623
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   624
        final Object toNonNullOpenValue(Object value)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
                throws OpenDataException {
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   626
            final Collection<?> valueCollection = (Collection<?>) value;
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   627
            if (valueCollection instanceof SortedSet<?>) {
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   628
                Comparator<?> comparator =
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   629
                    ((SortedSet<?>) valueCollection).comparator();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                if (comparator != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
                    final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                        "Cannot convert SortedSet with non-null comparator: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                        comparator;
831
50f701930577 6601652: MXBeans: no IllegalArgumentException in the ex. chain for SortedSet/Map with a non-null comparator()
emcmanus
parents: 687
diff changeset
   634
                    throw openDataException(msg, new IllegalArgumentException(msg));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
            final Object[] openArray = (Object[])
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                Array.newInstance(getOpenClass().getComponentType(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
                                  valueCollection.size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            int i = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
            for (Object o : valueCollection)
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   642
                openArray[i++] = elementMapping.toOpenValue(o);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
            return openArray;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   646
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   647
        final Object fromNonNullOpenValue(Object openValue)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                throws InvalidObjectException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
            final Object[] openArray = (Object[]) openValue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
            final Collection<Object> valueCollection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
            try {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   652
                valueCollection = cast(collectionClass.newInstance());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
            } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
                throw invalidObjectException("Cannot create collection", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            for (Object o : openArray) {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   657
                Object value = elementMapping.fromOpenValue(o);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
                if (!valueCollection.add(value)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                    final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
                        "Could not add " + o + " to " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
                        collectionClass.getName() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
                        " (duplicate set element?)";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
                    throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
            return valueCollection;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   669
        public void checkReconstructible() throws InvalidObjectException {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   670
            elementMapping.checkReconstructible();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   673
        private final Class<? extends Collection<?>> collectionClass;
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   674
        private final MXBeanMapping elementMapping;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   677
    private static final class MXBeanRefMapping extends NonNullMXBeanMapping {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   678
        MXBeanRefMapping(Type intf) {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   679
            super(intf, SimpleType.OBJECTNAME);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   682
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   683
        final Object toNonNullOpenValue(Object javaValue)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
                throws OpenDataException {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   685
            MXBeanLookup lookup = lookupNotNull(OpenDataException.class);
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   686
            ObjectName name = lookup.mxbeanToObjectName(javaValue);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
            if (name == null)
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   688
                throw new OpenDataException("No name for object: " + javaValue);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
            return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   692
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   693
        final Object fromNonNullOpenValue(Object openValue)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                throws InvalidObjectException {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   695
            MXBeanLookup lookup = lookupNotNull(InvalidObjectException.class);
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   696
            ObjectName name = (ObjectName) openValue;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
            Object mxbean =
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   698
                lookup.objectNameToMXBean(name, (Class<?>) getJavaType());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
            if (mxbean == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
                final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
                    "No MXBean for name: " + name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
                throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
            return mxbean;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   707
        private <T extends Exception> MXBeanLookup
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   708
            lookupNotNull(Class<T> excClass)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                throws T {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   710
            MXBeanLookup lookup = MXBeanLookup.getLookup();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
            if (lookup == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
                final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                    "Cannot convert MXBean interface in this context";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                T exc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
                    Constructor<T> con = excClass.getConstructor(String.class);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
                    exc = con.newInstance(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
                } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
                    throw new RuntimeException(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                throw exc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
            }
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   723
            return lookup;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   727
    private static final class TabularMapping extends NonNullMXBeanMapping {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   728
        TabularMapping(Type targetType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   729
                       boolean sortedMap,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   730
                       TabularType tabularType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   731
                       MXBeanMapping keyConverter,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   732
                       MXBeanMapping valueConverter) {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   733
            super(targetType, tabularType);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
            this.sortedMap = sortedMap;
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   735
            this.keyMapping = keyConverter;
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   736
            this.valueMapping = valueConverter;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   739
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   740
        final Object toNonNullOpenValue(Object value) throws OpenDataException {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   741
            final Map<Object, Object> valueMap = cast(value);
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   742
            if (valueMap instanceof SortedMap<?,?>) {
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   743
                Comparator<?> comparator = ((SortedMap<?,?>) valueMap).comparator();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                if (comparator != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                    final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
                        "Cannot convert SortedMap with non-null comparator: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
                        comparator;
831
50f701930577 6601652: MXBeans: no IllegalArgumentException in the ex. chain for SortedSet/Map with a non-null comparator()
emcmanus
parents: 687
diff changeset
   748
                    throw openDataException(msg, new IllegalArgumentException(msg));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
            final TabularType tabularType = (TabularType) getOpenType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
            final TabularData table = new TabularDataSupport(tabularType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
            final CompositeType rowType = tabularType.getRowType();
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   754
            for (Map.Entry<Object, Object> entry : valueMap.entrySet()) {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   755
                final Object openKey = keyMapping.toOpenValue(entry.getKey());
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   756
                final Object openValue = valueMapping.toOpenValue(entry.getValue());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                final CompositeData row;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                row =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                    new CompositeDataSupport(rowType, keyValueArray,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                                             new Object[] {openKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                                                           openValue});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                table.put(row);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
            return table;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   767
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   768
        final Object fromNonNullOpenValue(Object openValue)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
                throws InvalidObjectException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
            final TabularData table = (TabularData) openValue;
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   771
            final Collection<CompositeData> rows = cast(table.values());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
            final Map<Object, Object> valueMap =
1018
9f07e65e9653 6334663: TabularDataSupport should be able to return values in the insertion order
emcmanus
parents: 832
diff changeset
   773
                sortedMap ? newSortedMap() : newInsertionOrderMap();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
            for (CompositeData row : rows) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
                final Object key =
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   776
                    keyMapping.fromOpenValue(row.get("key"));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
                final Object value =
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   778
                    valueMapping.fromOpenValue(row.get("value"));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
                if (valueMap.put(key, value) != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
                    final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                        "Duplicate entry in TabularData: key=" + key;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
                    throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
            return valueMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   788
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   789
        public void checkReconstructible() throws InvalidObjectException {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   790
            keyMapping.checkReconstructible();
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   791
            valueMapping.checkReconstructible();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        private final boolean sortedMap;
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   795
        private final MXBeanMapping keyMapping;
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   796
        private final MXBeanMapping valueMapping;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   799
    private final class CompositeMapping extends NonNullMXBeanMapping {
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   800
        CompositeMapping(Class<?> targetClass,
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   801
                         CompositeType compositeType,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   802
                         String[] itemNames,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   803
                         Method[] getters,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   804
                         MXBeanMappingFactory factory) throws OpenDataException {
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   805
            super(targetClass, compositeType);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
            assert(itemNames.length == getters.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
            this.itemNames = itemNames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
            this.getters = getters;
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   811
            this.getterMappings = new MXBeanMapping[getters.length];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
            for (int i = 0; i < getters.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                Type retType = getters[i].getGenericReturnType();
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   814
                getterMappings[i] = factory.mappingForType(retType, factory);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   818
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   819
        final Object toNonNullOpenValue(Object value)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
                throws OpenDataException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
            CompositeType ct = (CompositeType) getOpenType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
            if (value instanceof CompositeDataView)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
                return ((CompositeDataView) value).toCompositeData(ct);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
            if (value == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
            Object[] values = new Object[getters.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
            for (int i = 0; i < getters.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
                    Object got = getters[i].invoke(value, (Object[]) null);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   831
                    values[i] = getterMappings[i].toOpenValue(got);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
                } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
                    throw openDataException("Error calling getter for " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
                                            itemNames[i] + ": " + e, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
            return new CompositeDataSupport(ct, itemNames, values);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
        /** Determine how to convert back from the CompositeData into
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
            the original Java type.  For a type that is not reconstructible,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
            this method will fail every time, and will throw the right
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
            exception. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
        private synchronized void makeCompositeBuilder()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
                throws InvalidObjectException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
            if (compositeBuilder != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   849
            Class<?> targetClass = (Class<?>) getJavaType();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
            /* In this 2D array, each subarray is a set of builders where
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
               there is no point in consulting the ones after the first if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
               the first refuses.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
            CompositeBuilder[][] builders = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
                    new CompositeBuilderViaFrom(targetClass, itemNames),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
                },
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
                    new CompositeBuilderViaConstructor(targetClass, itemNames),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
                },
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
                {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
                    new CompositeBuilderCheckGetters(targetClass, itemNames,
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   862
                                                     getterMappings),
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
                    new CompositeBuilderViaSetters(targetClass, itemNames),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
                    new CompositeBuilderViaProxy(targetClass, itemNames),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
                },
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
            };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
            CompositeBuilder foundBuilder = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
            /* We try to make a meaningful exception message by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
               concatenating each Builder's explanation of why it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
               isn't applicable.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
            final StringBuilder whyNots = new StringBuilder();
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   872
            Throwable possibleCause = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
        find:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
            for (CompositeBuilder[] relatedBuilders : builders) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                for (int i = 0; i < relatedBuilders.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                    CompositeBuilder builder = relatedBuilders[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
                    String whyNot = builder.applicable(getters);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
                    if (whyNot == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
                        foundBuilder = builder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
                        break find;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
                    }
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   882
                    Throwable cause = builder.possibleCause();
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   883
                    if (cause != null)
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   884
                        possibleCause = cause;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
                    if (whyNot.length() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
                        if (whyNots.length() > 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
                            whyNots.append("; ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                        whyNots.append(whyNot);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
                        if (i == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
                           break; // skip other builders in this group
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
            if (foundBuilder == null) {
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   895
                String msg =
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
                    "Do not know how to make a " + targetClass.getName() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
                    " from a CompositeData: " + whyNots;
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   898
                if (possibleCause != null)
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   899
                    msg += ". Remaining exceptions show a POSSIBLE cause.";
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   900
                throw invalidObjectException(msg, possibleCause);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
            compositeBuilder = foundBuilder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   905
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   906
        public void checkReconstructible() throws InvalidObjectException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
            makeCompositeBuilder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   910
        @Override
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   911
        final Object fromNonNullOpenValue(Object value)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
                throws InvalidObjectException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
            makeCompositeBuilder();
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   914
            return compositeBuilder.fromCompositeData((CompositeData) value,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
                                                      itemNames,
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   916
                                                      getterMappings);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
        private final String[] itemNames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
        private final Method[] getters;
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   921
        private final MXBeanMapping[] getterMappings;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
        private CompositeBuilder compositeBuilder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
    /** Converts from a CompositeData to an instance of the targetClass.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
    private static abstract class CompositeBuilder {
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   927
        CompositeBuilder(Class<?> targetClass, String[] itemNames) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
            this.targetClass = targetClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
            this.itemNames = itemNames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
        Class<?> getTargetClass() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
            return targetClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
        String[] getItemNames() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
            return itemNames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
        /** If the subclass is appropriate for targetClass, then the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
            method returns null.  If the subclass is not appropriate,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
            then the method returns an explanation of why not.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
            subclass should be appropriate but there is a problem,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
            then the method throws InvalidObjectException.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
        abstract String applicable(Method[] getters)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
                throws InvalidObjectException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   948
        /** If the subclass returns an explanation of why it is not applicable,
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   949
            it can additionally indicate an exception with details.  This is
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   950
            potentially confusing, because the real problem could be that one
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   951
            of the other subclasses is supposed to be applicable but isn't.
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   952
            But the advantage of less information loss probably outweighs the
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   953
            disadvantage of possible confusion.  */
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   954
        Throwable possibleCause() {
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   955
            return null;
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   956
        }
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   957
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   958
        abstract Object fromCompositeData(CompositeData cd,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
                                          String[] itemNames,
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
   960
                                          MXBeanMapping[] converters)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
                throws InvalidObjectException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
        private final Class<?> targetClass;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
        private final String[] itemNames;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
    /** Builder for when the target class has a method "public static
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
        from(CompositeData)".  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
    private static final class CompositeBuilderViaFrom
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
            extends CompositeBuilder {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   972
        CompositeBuilderViaFrom(Class<?> targetClass, String[] itemNames) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
            super(targetClass, itemNames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
        String applicable(Method[] getters) throws InvalidObjectException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
            // See if it has a method "T from(CompositeData)"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
            // as is conventional for a CompositeDataView
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
            Class<?> targetClass = getTargetClass();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
                Method fromMethod =
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
   982
                    targetClass.getMethod("from", CompositeData.class);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
                if (!Modifier.isStatic(fromMethod.getModifiers())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
                    final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
                        "Method from(CompositeData) is not static";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
                    throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
                if (fromMethod.getReturnType() != getTargetClass()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
                    final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
                        "Method from(CompositeData) returns " +
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   993
                        typeName(fromMethod.getReturnType()) +
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
   994
                        " not " + typeName(targetClass);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                    throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
                this.fromMethod = fromMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
                return null; // success!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
            } catch (InvalidObjectException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
                throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
            } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
                // OK: it doesn't have the method
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
                return "no method from(CompositeData)";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1008
        final Object fromCompositeData(CompositeData cd,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1009
                                       String[] itemNames,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1010
                                       MXBeanMapping[] converters)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
                throws InvalidObjectException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
                return fromMethod.invoke(null, cd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
            } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
                final String msg = "Failed to invoke from(CompositeData)";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
                throw invalidObjectException(msg, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
        private Method fromMethod;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
    /** This builder never actually returns success.  It simply serves
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
        to check whether the other builders in the same group have any
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
        chance of success.  If any getter in the targetClass returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
        a type that we don't know how to reconstruct, then we will
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
        not be able to make a builder, and there is no point in repeating
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
        the error about the problematic getter as many times as there are
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
        candidate builders.  Instead, the "applicable" method will return
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
        an explanatory string, and the other builders will be skipped.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
        If all the getters are OK, then the "applicable" method will return
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
        an empty string and the other builders will be tried.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
    private static class CompositeBuilderCheckGetters extends CompositeBuilder {
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
  1034
        CompositeBuilderCheckGetters(Class<?> targetClass, String[] itemNames,
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1035
                                     MXBeanMapping[] getterConverters) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
            super(targetClass, itemNames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
            this.getterConverters = getterConverters;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
        String applicable(Method[] getters) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
            for (int i = 0; i < getters.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
                    getterConverters[i].checkReconstructible();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
                } catch (InvalidObjectException e) {
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1045
                    possibleCause = e;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
                    return "method " + getters[i].getName() + " returns type " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
                        "that cannot be mapped back from OpenData";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
            return "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1053
        @Override
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1054
        Throwable possibleCause() {
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1055
            return possibleCause;
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1056
        }
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1057
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1058
        final Object fromCompositeData(CompositeData cd,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
                                       String[] itemNames,
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1060
                                       MXBeanMapping[] converters) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
            throw new Error();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1064
        private final MXBeanMapping[] getterConverters;
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1065
        private Throwable possibleCause;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
    /** Builder for when the target class has a setter for every getter. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
    private static class CompositeBuilderViaSetters extends CompositeBuilder {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1071
        CompositeBuilderViaSetters(Class<?> targetClass, String[] itemNames) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
            super(targetClass, itemNames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
        String applicable(Method[] getters) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
            try {
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1077
                Constructor<?> c = getTargetClass().getConstructor();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
            } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
                return "does not have a public no-arg constructor";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
            Method[] setters = new Method[getters.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
            for (int i = 0; i < getters.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
                Method getter = getters[i];
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
  1085
                Class<?> returnType = getter.getReturnType();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
                String name = propertyName(getter);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
                String setterName = "set" + name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
                Method setter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
                    setter = getTargetClass().getMethod(setterName, returnType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
                    if (setter.getReturnType() != void.class)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
                        throw new Exception();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
                } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
                    return "not all getters have corresponding setters " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
                           "(" + getter + ")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
                setters[i] = setter;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
            this.setters = setters;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1103
        Object fromCompositeData(CompositeData cd,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
                                 String[] itemNames,
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1105
                                 MXBeanMapping[] converters)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
                throws InvalidObjectException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
            Object o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
                o = getTargetClass().newInstance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
                for (int i = 0; i < itemNames.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
                    if (cd.containsKey(itemNames[i])) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
                        Object openItem = cd.get(itemNames[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
                        Object javaItem =
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1114
                            converters[i].fromOpenValue(openItem);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
                        setters[i].invoke(o, javaItem);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
            } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
                throw invalidObjectException(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
            return o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
        private Method[] setters;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
    /** Builder for when the target class has a constructor that is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
        annotated with @ConstructorProperties so we can see the correspondence
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
        to getters.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
    private static final class CompositeBuilderViaConstructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
            extends CompositeBuilder {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
  1133
        CompositeBuilderViaConstructor(Class<?> targetClass, String[] itemNames) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
            super(targetClass, itemNames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
        String applicable(Method[] getters) throws InvalidObjectException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
            final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
  1141
            Class<?> targetClass = getTargetClass();
1221
e3dc70e4e610 6746196: Some JMX classes do not compile with Eclipse compiler
emcmanus
parents: 1018
diff changeset
  1142
            Constructor<?>[] constrs = targetClass.getConstructors();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
            // Applicable if and only if there are any annotated constructors
1221
e3dc70e4e610 6746196: Some JMX classes do not compile with Eclipse compiler
emcmanus
parents: 1018
diff changeset
  1145
            List<Constructor<?>> annotatedConstrList = newList();
268
aa06754a95de 6643627: JMX source code includes incorrect Java code
emcmanus
parents: 2
diff changeset
  1146
            for (Constructor<?> constr : constrs) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
                if (Modifier.isPublic(constr.getModifiers())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
                        && constr.getAnnotation(propertyNamesClass) != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
                    annotatedConstrList.add(constr);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
            if (annotatedConstrList.isEmpty())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
                return "no constructor has @ConstructorProperties annotation";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
            annotatedConstructors = newList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
            // Now check that all the annotated constructors are valid
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
            // and throw an exception if not.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
            // First link the itemNames to their getter indexes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
            Map<String, Integer> getterMap = newMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
            String[] itemNames = getItemNames();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
            for (int i = 0; i < itemNames.length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
                getterMap.put(itemNames[i], i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
            // Run through the constructors making the checks in the spec.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
            // For each constructor, remember the correspondence between its
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
            // parameters and the items.  The int[] for a constructor says
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
            // what parameter index should get what item.  For example,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
            // if element 0 is 2 then that means that item 0 in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
            // CompositeData goes to parameter 2 of the constructor.  If an
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
            // element is -1, that item isn't given to the constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
            // Also remember the set of properties in that constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
            // so we can test unambiguity.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
            Set<BitSet> getterIndexSets = newSet();
1221
e3dc70e4e610 6746196: Some JMX classes do not compile with Eclipse compiler
emcmanus
parents: 1018
diff changeset
  1176
            for (Constructor<?> constr : annotatedConstrList) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
                String[] propertyNames =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
                    constr.getAnnotation(propertyNamesClass).value();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
                Type[] paramTypes = constr.getGenericParameterTypes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
                if (paramTypes.length != propertyNames.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
                    final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
                        "Number of constructor params does not match " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
                        "@ConstructorProperties annotation: " + constr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
                    throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
                int[] paramIndexes = new int[getters.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
                for (int i = 0; i < getters.length; i++)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
                    paramIndexes[i] = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
                BitSet present = new BitSet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
                for (int i = 0; i < propertyNames.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
                    String propertyName = propertyNames[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
                    if (!getterMap.containsKey(propertyName)) {
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1196
                        String msg =
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
                            "@ConstructorProperties includes name " + propertyName +
1512
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1198
                            " which does not correspond to a property";
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1199
                        for (String getterName : getterMap.keySet()) {
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1200
                            if (getterName.equalsIgnoreCase(propertyName)) {
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1201
                                msg += " (differs only in case from property " +
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1202
                                        getterName + ")";
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1203
                            }
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1204
                        }
0f8eb7ad4ef5 6763051: MXBean: Incorrect type names for parametrized dealing with arrays (openType)
emcmanus
parents: 1510
diff changeset
  1205
                        msg += ": " + constr;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
                        throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
                    int getterIndex = getterMap.get(propertyName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
                    paramIndexes[getterIndex] = i;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
                    if (present.get(getterIndex)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
                        final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
                            "@ConstructorProperties contains property " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
                            propertyName + " more than once: " + constr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
                        throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
                    present.set(getterIndex);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
                    Method getter = getters[getterIndex];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
                    Type propertyType = getter.getGenericReturnType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
                    if (!propertyType.equals(paramTypes[i])) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
                        final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
                            "@ConstructorProperties gives property " + propertyName +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
                            " of type " + propertyType + " for parameter " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
                            " of type " + paramTypes[i] + ": " + constr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
                        throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
                if (!getterIndexSets.add(present)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
                    final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
                        "More than one constructor has a @ConstructorProperties " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
                        "annotation with this set of names: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
                        Arrays.toString(propertyNames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
                    throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
                Constr c = new Constr(constr, paramIndexes, present);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
                annotatedConstructors.add(c);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
            /* Check that no possible set of items could lead to an ambiguous
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
             * choice of constructor (spec requires this check).  For any
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
             * pair of constructors, their union would be the minimal
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
             * ambiguous set.  If this set itself corresponds to a constructor,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
             * there is no ambiguity for that pair.  In the usual case, one
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
             * of the constructors is a superset of the other so the union is
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
             * just the bigger constuctor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
             *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
             * The algorithm here is quadratic in the number of constructors
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
             * with a @ConstructorProperties annotation.  Typically this corresponds
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
             * to the number of versions of the class there have been.  Ten
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
             * would already be a large number, so although it's probably
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
             * possible to have an O(n lg n) algorithm it wouldn't be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
             * worth the complexity.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
            for (BitSet a : getterIndexSets) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
                boolean seen = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
                for (BitSet b : getterIndexSets) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
                    if (a == b)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
                        seen = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
                    else if (seen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
                        BitSet u = new BitSet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
                        u.or(a); u.or(b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
                        if (!getterIndexSets.contains(u)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
                            Set<String> names = new TreeSet<String>();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
                            for (int i = u.nextSetBit(0); i >= 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
                                 i = u.nextSetBit(i+1))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
                                names.add(itemNames[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
                            final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
                                "Constructors with @ConstructorProperties annotation " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
                                " would be ambiguous for these items: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
                                names;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
                            throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
            return null; // success!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1281
        final Object fromCompositeData(CompositeData cd,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1282
                                       String[] itemNames,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1283
                                       MXBeanMapping[] mappings)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
                throws InvalidObjectException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
            // The CompositeData might come from an earlier version where
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
            // not all the items were present.  We look for a constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
            // that accepts just the items that are present.  Because of
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
            // the ambiguity check in applicable(), we know there must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
            // at most one maximally applicable constructor.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
            CompositeType ct = cd.getCompositeType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
            BitSet present = new BitSet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
            for (int i = 0; i < itemNames.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
                if (ct.getType(itemNames[i]) != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
                    present.set(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
            Constr max = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
            for (Constr constr : annotatedConstructors) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
                if (subset(constr.presentParams, present) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
                        (max == null ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
                         subset(max.presentParams, constr.presentParams)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
                    max = constr;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
            if (max == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
                final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
                    "No constructor has a @ConstructorProperties for this set of " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
                    "items: " + ct.keySet();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
                throw new InvalidObjectException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
            Object[] params = new Object[max.presentParams.cardinality()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
            for (int i = 0; i < itemNames.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
                if (!max.presentParams.get(i))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
                    continue;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
                Object openItem = cd.get(itemNames[i]);
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1317
                Object javaItem = mappings[i].fromOpenValue(openItem);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
                int index = max.paramIndexes[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
                if (index >= 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
                    params[index] = javaItem;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
                return max.constructor.newInstance(params);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
            } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
                final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
                    "Exception constructing " + getTargetClass().getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
                throw invalidObjectException(msg, e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
        private static boolean subset(BitSet sub, BitSet sup) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
            BitSet subcopy = (BitSet) sub.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
            subcopy.andNot(sup);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
            return subcopy.isEmpty();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
        private static class Constr {
1221
e3dc70e4e610 6746196: Some JMX classes do not compile with Eclipse compiler
emcmanus
parents: 1018
diff changeset
  1339
            final Constructor<?> constructor;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
            final int[] paramIndexes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
            final BitSet presentParams;
1221
e3dc70e4e610 6746196: Some JMX classes do not compile with Eclipse compiler
emcmanus
parents: 1018
diff changeset
  1342
            Constr(Constructor<?> constructor, int[] paramIndexes,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
                   BitSet presentParams) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
                this.constructor = constructor;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
                this.paramIndexes = paramIndexes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
                this.presentParams = presentParams;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
        private List<Constr> annotatedConstructors;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
    /** Builder for when the target class is an interface and contains
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
        no methods other than getters.  Then we can make an instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
        using a dynamic proxy that forwards the getters to the source
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
        CompositeData.  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
    private static final class CompositeBuilderViaProxy
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
            extends CompositeBuilder {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
  1360
        CompositeBuilderViaProxy(Class<?> targetClass, String[] itemNames) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
            super(targetClass, itemNames);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
        String applicable(Method[] getters) {
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
  1365
            Class<?> targetClass = getTargetClass();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
            if (!targetClass.isInterface())
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
                return "not an interface";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
            Set<Method> methods =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
                newSet(Arrays.asList(targetClass.getMethods()));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
            methods.removeAll(Arrays.asList(getters));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
            /* If the interface has any methods left over, they better be
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
             * public methods that are already present in java.lang.Object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
            String bad = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
            for (Method m : methods) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
                String mname = m.getName();
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
  1377
                Class<?>[] mparams = m.getParameterTypes();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
                try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
                    Method om = Object.class.getMethod(mname, mparams);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
                    if (!Modifier.isPublic(om.getModifiers()))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
                        bad = mname;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
                } catch (NoSuchMethodException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
                    bad = mname;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
                /* We don't catch SecurityException since it shouldn't
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
                 * happen for a method in Object and if it does we would
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
                 * like to know about it rather than mysteriously complaining.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
                 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
            if (bad != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
                return "contains methods other than getters (" + bad + ")";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
            return null; // success!
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
687
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1395
        final Object fromCompositeData(CompositeData cd,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1396
                                       String[] itemNames,
874e25a9844a 6562936: Support custom type mappings in MXBeans
emcmanus
parents: 287
diff changeset
  1397
                                       MXBeanMapping[] converters) {
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
  1398
            final Class<?> targetClass = getTargetClass();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
            return
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
                Proxy.newProxyInstance(targetClass.getClassLoader(),
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
  1401
                                       new Class<?>[] {targetClass},
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
                                       new CompositeDataInvocationHandler(cd));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
    static InvalidObjectException invalidObjectException(String msg,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
                                                         Throwable cause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
        return EnvHelp.initCause(new InvalidObjectException(msg), cause);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
    static InvalidObjectException invalidObjectException(Throwable cause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
        return invalidObjectException(cause.getMessage(), cause);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
    static OpenDataException openDataException(String msg, Throwable cause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
        return EnvHelp.initCause(new OpenDataException(msg), cause);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
    static OpenDataException openDataException(Throwable cause) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
        return openDataException(cause.getMessage(), cause);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
  1423
    static void mustBeComparable(Class<?> collection, Type element)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
            throws OpenDataException {
1510
e747d3193ef2 6763639: Remove "rawtypes" warnings from JMX code
emcmanus
parents: 1221
diff changeset
  1425
        if (!(element instanceof Class<?>)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
            || !Comparable.class.isAssignableFrom((Class<?>) element)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
            final String msg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
                "Parameter class " + element + " of " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
                collection.getName() + " does not implement " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
                Comparable.class.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
            throw new OpenDataException(msg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
     * Utility method to take a string and convert it to normal Java variable
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
     * name capitalization.  This normally means converting the first
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
     * character from upper case to lower case, but in the (unusual) special
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
     * case when there is more than one character and both the first and
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
     * second characters are upper case, we leave it alone.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
     * Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
     * as "URL".
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
     * @param  name The string to be decapitalized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
     * @return  The decapitalized version of the string.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
    public static String decapitalize(String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
        if (name == null || name.length() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
            return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
        int offset1 = Character.offsetByCodePoints(name, 0, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
        // Should be name.offsetByCodePoints but 6242664 makes this fail
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
        if (offset1 < name.length() &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
                Character.isUpperCase(name.codePointAt(offset1)))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
            return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
        return name.substring(0, offset1).toLowerCase() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
               name.substring(offset1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
     * Reverse operation for java.beans.Introspector.decapitalize.  For any s,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
     * capitalize(decapitalize(s)).equals(s).  The reverse is not true:
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
     * e.g. capitalize("uRL") produces "URL" which is unchanged by
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
     * decapitalize.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
    static String capitalize(String name) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
        if (name == null || name.length() == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
            return name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
        int offset1 = name.offsetByCodePoints(0, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
        return name.substring(0, offset1).toUpperCase() +
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
               name.substring(offset1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
    public static String propertyName(Method m) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
        String rest = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
        String name = m.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
        if (name.startsWith("get"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
            rest = name.substring(3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
        else if (name.startsWith("is") && m.getReturnType() == boolean.class)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
            rest = name.substring(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
        if (rest == null || rest.length() == 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
            || m.getParameterTypes().length > 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
            || m.getReturnType() == void.class
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
            || name.equals("getClass"))
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
        return rest;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
    private final static Map<Type, Type> inProgress = newIdentityHashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
    // really an IdentityHashSet but that doesn't exist
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
}