jdk/src/java.desktop/share/classes/com/sun/beans/introspect/PropertyInfo.java
author serb
Tue, 02 Jun 2015 19:27:06 +0300
changeset 31162 b4c9194f282c
parent 25859 3317bb8137f4
child 32109 b89c59200379
permissions -rw-r--r--
8079084: Behavior of BeanProperty.enumerationValues() contradicts spec Reviewed-by: alexsch, malenkov
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
25566
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
     1
/*
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
     2
 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
     4
 *
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    10
 *
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    15
 * accompanied this code).
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    16
 *
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    20
 *
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    23
 * questions.
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    24
 */
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    25
package com.sun.beans.introspect;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    26
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    27
import java.beans.BeanProperty;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    28
import java.lang.reflect.Field;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    29
import java.lang.reflect.Method;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    30
import java.lang.reflect.Modifier;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    31
import java.lang.reflect.Type;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    32
import java.util.ArrayList;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    33
import java.util.Collections;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    34
import java.util.EnumMap;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    35
import java.util.Iterator;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    36
import java.util.List;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    37
import java.util.Map;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    38
import java.util.TreeMap;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    39
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    40
import static com.sun.beans.finder.ClassFinder.findClass;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    41
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    42
public final class PropertyInfo {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    43
    public enum Name {bound, expert, hidden, preferred, visualUpdate, description, enumerationValues}
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    44
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    45
    private static final String VETO_EXCEPTION_NAME = "java.beans.PropertyVetoException";
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    46
    private static final Class<?> VETO_EXCEPTION;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    47
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    48
    static {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    49
        Class<?> type;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    50
        try {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    51
            type = Class.forName(VETO_EXCEPTION_NAME);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    52
        } catch (Exception exception) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    53
            type = null;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    54
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    55
        VETO_EXCEPTION = type;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    56
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    57
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    58
    private Class<?> type;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    59
    private MethodInfo read;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    60
    private MethodInfo write;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    61
    private PropertyInfo indexed;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    62
    private List<MethodInfo> readList;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    63
    private List<MethodInfo> writeList;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    64
    private Map<Name,Object> map;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    65
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    66
    private PropertyInfo() {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    67
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    68
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    69
    private boolean initialize() {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    70
        if (this.read != null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    71
            this.type = this.read.type;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    72
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    73
        if (this.readList != null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    74
            for (MethodInfo info : this.readList) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    75
                if ((this.read == null) || this.read.type.isAssignableFrom(info.type)) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    76
                    this.read = info;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    77
                    this.type = info.type;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    78
                }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    79
            }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    80
            this.readList = null;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    81
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    82
        if (this.writeList != null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    83
            for (MethodInfo info : this.writeList) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    84
                if (this.type == null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    85
                    this.write = info;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    86
                    this.type = info.type;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    87
                } else if (this.type.isAssignableFrom(info.type)) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    88
                    if ((this.write == null) || this.write.type.isAssignableFrom(info.type)) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    89
                        this.write = info;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    90
                    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    91
                }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    92
            }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    93
            this.writeList = null;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    94
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    95
        if (this.indexed != null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    96
            if ((this.type != null) && !this.type.isArray()) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    97
                this.indexed = null; // property type is not an array
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    98
            } else if (!this.indexed.initialize()) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
    99
                this.indexed = null; // cannot initialize indexed methods
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   100
            } else if ((this.type != null) && (this.indexed.type != this.type.getComponentType())) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   101
                this.indexed = null; // different property types
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   102
            } else {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   103
                this.map = this.indexed.map;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   104
                this.indexed.map = null;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   105
            }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   106
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   107
        if ((this.type == null) && (this.indexed == null)) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   108
            return false;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   109
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   110
        initialize(this.write);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   111
        initialize(this.read);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   112
        return true;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   113
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   114
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   115
    private void initialize(MethodInfo info) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   116
        if (info != null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   117
            BeanProperty annotation = info.method.getAnnotation(BeanProperty.class);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   118
            if (annotation != null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   119
                if (!annotation.bound()) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   120
                    put(Name.bound, Boolean.FALSE);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   121
                }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   122
                put(Name.expert, annotation.expert());
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   123
                put(Name.hidden, annotation.hidden());
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   124
                put(Name.preferred, annotation.preferred());
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   125
                put(Name.visualUpdate, annotation.visualUpdate());
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   126
                put(Name.description, annotation.description());
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   127
                String[] values = annotation.enumerationValues();
31162
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   128
                try {
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   129
                    Object[] array = new Object[3 * values.length];
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   130
                    int index = 0;
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   131
                    for (String value : values) {
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   132
                        Class<?> type = info.method.getDeclaringClass();
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   133
                        String name = value;
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   134
                        int pos = value.lastIndexOf('.');
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   135
                        if (pos > 0) {
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   136
                            name = value.substring(0, pos);
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   137
                            if (name.indexOf('.') < 0) {
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   138
                                String pkg = type.getName();
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   139
                                name = pkg.substring(0, 1 + Math.max(
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   140
                                        pkg.lastIndexOf('.'),
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   141
                                        pkg.lastIndexOf('$'))) + name;
25566
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   142
                            }
31162
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   143
                            type = findClass(name);
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   144
                            name = value.substring(pos + 1);
25566
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   145
                        }
31162
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   146
                        Field field = type.getField(name);
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   147
                        if (Modifier.isStatic(field.getModifiers()) && info.type.isAssignableFrom(field.getType())) {
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   148
                            array[index++] = name;
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   149
                            array[index++] = field.get(null);
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   150
                            array[index++] = value;
25566
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   151
                        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   152
                    }
31162
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   153
                    if (index == array.length) {
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   154
                        put(Name.enumerationValues, array);
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   155
                    }
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   156
                } catch (Exception ignored) {
b4c9194f282c 8079084: Behavior of BeanProperty.enumerationValues() contradicts spec
serb
parents: 25859
diff changeset
   157
                    ignored.printStackTrace();
25566
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   158
                }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   159
            }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   160
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   161
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   162
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   163
    public Class<?> getPropertyType() {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   164
        return this.type;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   165
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   166
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   167
    public Method getReadMethod() {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   168
        return (this.read == null) ? null : this.read.method;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   169
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   170
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   171
    public Method getWriteMethod() {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   172
        return (this.write == null) ? null : this.write.method;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   173
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   174
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   175
    public PropertyInfo getIndexed() {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   176
        return this.indexed;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   177
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   178
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   179
    public boolean isConstrained() {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   180
        if (this.write != null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   181
            if (VETO_EXCEPTION == null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   182
                for (Class<?> type : this.write.method.getExceptionTypes()) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   183
                    if (type.getName().equals(VETO_EXCEPTION_NAME)) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   184
                        return true;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   185
                    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   186
                }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   187
            } else if (this.write.isThrow(VETO_EXCEPTION)) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   188
                return true;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   189
            }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   190
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   191
        return (this.indexed != null) && this.indexed.isConstrained();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   192
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   193
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   194
    public boolean is(Name name) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   195
        Object value = get(name);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   196
        return (value instanceof Boolean)
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   197
                ? (Boolean) value
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   198
                : Name.bound.equals(name);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   199
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   200
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   201
    public Object get(Name name) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   202
        return this.map == null ? null : this.map.get(name);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   203
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   204
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   205
    private void put(Name name, boolean value) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   206
        if (value) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   207
            put(name, Boolean.TRUE);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   208
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   209
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   210
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   211
    private void put(Name name, String value) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   212
        if (0 < value.length()) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   213
            put(name, (Object) value);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   214
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   215
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   216
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   217
    private void put(Name name, Object value) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   218
        if (this.map == null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   219
            this.map = new EnumMap<>(Name.class);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   220
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   221
        this.map.put(name, value);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   222
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   223
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   224
    private static List<MethodInfo> add(List<MethodInfo> list, Method method, Type type) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   225
        if (list == null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   226
            list = new ArrayList<>();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   227
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   228
        list.add(new MethodInfo(method, type));
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   229
        return list;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   230
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   231
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   232
    private static boolean isPrefix(String name, String prefix) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   233
        return name.length() > prefix.length() && name.startsWith(prefix);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   234
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   235
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   236
    private static PropertyInfo getInfo(Map<String,PropertyInfo> map, String key, boolean indexed) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   237
        PropertyInfo info = map.get(key);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   238
        if (info == null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   239
            info = new PropertyInfo();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   240
            map.put(key, info);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   241
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   242
        if (!indexed) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   243
            return info;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   244
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   245
        if (info.indexed == null) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   246
            info.indexed = new PropertyInfo();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   247
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   248
        return info.indexed;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   249
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   250
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   251
    public static Map<String,PropertyInfo> get(Class<?> type) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   252
        List<Method> methods = ClassInfo.get(type).getMethods();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   253
        if (methods.isEmpty()) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   254
            return Collections.emptyMap();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   255
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   256
        Map<String,PropertyInfo> map = new TreeMap<>();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   257
        for (Method method : methods) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   258
            if (!Modifier.isStatic(method.getModifiers())) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   259
                Class<?> returnType = method.getReturnType();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   260
                String name = method.getName();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   261
                switch (method.getParameterCount()) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   262
                    case 0:
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   263
                        if (returnType.equals(boolean.class) && isPrefix(name, "is")) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   264
                            PropertyInfo info = getInfo(map, name.substring(2), false);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   265
                            info.read = new MethodInfo(method, boolean.class);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   266
                        } else if (!returnType.equals(void.class) && isPrefix(name, "get")) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   267
                            PropertyInfo info = getInfo(map, name.substring(3), false);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   268
                            info.readList = add(info.readList, method, method.getGenericReturnType());
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   269
                        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   270
                        break;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   271
                    case 1:
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   272
                        if (returnType.equals(void.class) && isPrefix(name, "set")) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   273
                            PropertyInfo info = getInfo(map, name.substring(3), false);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   274
                            info.writeList = add(info.writeList, method, method.getGenericParameterTypes()[0]);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   275
                        } else if (!returnType.equals(void.class) && method.getParameterTypes()[0].equals(int.class) && isPrefix(name, "get")) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   276
                            PropertyInfo info = getInfo(map, name.substring(3), true);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   277
                            info.readList = add(info.readList, method, method.getGenericReturnType());
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   278
                        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   279
                        break;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   280
                    case 2:
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   281
                        if (returnType.equals(void.class) && method.getParameterTypes()[0].equals(int.class) && isPrefix(name, "set")) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   282
                            PropertyInfo info = getInfo(map, name.substring(3), true);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   283
                            info.writeList = add(info.writeList, method, method.getGenericParameterTypes()[1]);
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   284
                        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   285
                        break;
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   286
                }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   287
            }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   288
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   289
        Iterator<PropertyInfo> iterator = map.values().iterator();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   290
        while (iterator.hasNext()) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   291
            if (!iterator.next().initialize()) {
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   292
                iterator.remove();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   293
            }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   294
        }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   295
        return !map.isEmpty()
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   296
                ? Collections.unmodifiableMap(map)
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   297
                : Collections.emptyMap();
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   298
    }
ba387c302edd 4058433: RFE: tool for creating BeanInfo template
malenkov
parents:
diff changeset
   299
}