1/*
2 * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 4619536
27 * @summary Tests resolving the ambiguities in the resolution of IndexedPropertyDescriptors
28 * @author Mark Davidson
29 */
30
31import java.beans.IndexedPropertyDescriptor;
32import java.beans.PropertyDescriptor;
33import java.util.Date;
34
35public class Test4619536 {
36    public static void main(String[] args) throws Exception {
37        IndexedPropertyDescriptor ipd = BeanUtils.getIndexedPropertyDescriptor(A.class, "foo");
38        if (!ipd.getIndexedPropertyType().equals(String.class)) {
39            error(ipd, "A.foo should be String type");
40        }
41        PropertyDescriptor pd = BeanUtils.findPropertyDescriptor(B.class, "foo");
42        if (pd instanceof IndexedPropertyDescriptor) {
43            error(pd, "B.foo should not be an indexed property");
44        }
45        if (!pd.getPropertyType().equals(Date.class)) {
46            error(pd, "B.foo should be Date type");
47        }
48        pd = BeanUtils.findPropertyDescriptor(Child.class, "foo");
49        if (pd instanceof IndexedPropertyDescriptor) {
50            error(pd, "Child.foo should not be an indexed property");
51        }
52        pd = BeanUtils.findPropertyDescriptor(Classic.class, "foo");
53        if (pd instanceof IndexedPropertyDescriptor) {
54            error(pd, "Classic.foo should not be an indexed property");
55        }
56        ipd = BeanUtils.getIndexedPropertyDescriptor(Index.class, "foo");
57        if (!hasIPD(ipd)) {
58            error(pd, "Index.foo should have ipd values");
59        }
60        if (hasPD(ipd)) {
61            error(ipd, "Index.foo should not have pd values");
62        }
63        ipd = BeanUtils.getIndexedPropertyDescriptor(All.class, "foo");
64        if (!hasPD(ipd) || !hasIPD(ipd)) {
65            error(ipd, "All.foo should have all pd/ipd values");
66        }
67        if (!isValidType(ipd)) {
68            error(ipd, "All.foo pdType should equal ipdType");
69        }
70        ipd = BeanUtils.getIndexedPropertyDescriptor(Getter.class, "foo");
71        if (ipd.getReadMethod() == null || ipd.getWriteMethod() != null) {
72            error(ipd, "Getter.foo classic methods incorrect");
73        }
74        if (!isValidType(ipd)) {
75            error(ipd, "Getter.foo pdType should equal ipdType");
76        }
77        ipd = BeanUtils.getIndexedPropertyDescriptor(BadGetter.class, "foo");
78        if (hasPD(ipd)) {
79            error(ipd, "BadGetter.foo should not have classic methods");
80        }
81        ipd = BeanUtils.getIndexedPropertyDescriptor(Setter.class, "foo");
82        if (ipd.getReadMethod() != null || ipd.getWriteMethod() == null) {
83            error(ipd, "Setter.foo classic methods incorrect");
84        }
85        if (!isValidType(ipd)) {
86            error(ipd, "Setter.foo pdType should equal ipdType");
87        }
88        ipd = BeanUtils.getIndexedPropertyDescriptor(BadSetter.class, "foo");
89        if (hasPD(ipd)) {
90            error(ipd, "BadSetter.foo should not have classic methods");
91        }
92    }
93
94    public static boolean hasPD(PropertyDescriptor pd) {
95        if (null == pd.getPropertyType()) {
96            return false;
97        }
98        return (null != pd.getReadMethod())
99            || (null != pd.getWriteMethod());
100    }
101
102    public static boolean hasIPD(IndexedPropertyDescriptor ipd) {
103        if (null == ipd.getIndexedPropertyType()) {
104            return false;
105        }
106        return (null != ipd.getIndexedReadMethod())
107            || (null != ipd.getIndexedWriteMethod());
108    }
109
110    public static boolean isValidType(IndexedPropertyDescriptor ipd) {
111        Class type = ipd.getPropertyType();
112        return type.isArray() && type.getComponentType().equals(ipd.getIndexedPropertyType());
113    }
114
115    public static void error(PropertyDescriptor pd, String message) {
116        BeanUtils.reportPropertyDescriptor(pd);
117        throw new Error(message);
118    }
119
120    // Test case from 4619536
121    public static class A {
122        // prop foo on A should be indexed of type String
123        public String getFoo(int x) {
124            return null;
125        }
126    }
127
128    public static class B extends A {
129        // prop foo on should be non-indexed of type Date
130        public Date getFoo() {
131            return null;
132        }
133    }
134
135    // Test case from 4812428 (this works in 1.5.0)
136    public static class Parent {
137        public void setFoo(String foo) {
138        }
139
140        public Child getFoo(int index) {
141            return null;
142        }
143    }
144
145    public static class Child extends Parent {
146        public Child getFoo() {
147            return null;
148        }
149    }
150
151    // This class has a complete set of pd
152    public static class Classic {
153        public String[] getFoo() {
154            return null;
155        }
156
157        public void setFoo(String[] foo) {
158        }
159    }
160
161    // This class has a complete set of ipd
162    public static class Index {
163        public String getFoo(int i) {
164            return null;
165        }
166
167        public void setFoo(int i, String f) {
168        }
169    }
170
171    // This class adds a proper getter and setter
172    public static class All extends Index {
173        public String[] getFoo() {
174            return null;
175        }
176
177        public void setFoo(String[] foo) {
178        }
179    }
180
181    // This class adds a classic getter
182    public static class Getter extends Index {
183        public String[] getFoo() {
184            return null;
185        }
186    }
187
188    // This class has an alternate getter and should be merged
189    public static class BadGetter extends Index {
190        public String getFoo() {
191            return null;
192        }
193    }
194
195    // This class adds a classic setter
196    public static class Setter extends Index {
197        public void setFoo(String[] f) {
198        }
199    }
200
201    // This class has an alternate setter and should be merged
202    public static class BadSetter extends Index {
203        public void setFoo(String f) {
204        }
205    }
206}
207