1 /*
2  * Copyright (c) 2012, 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 7193977
27  * @summary Tests that generified property descriptors do not loose additional info
28  * @author Sergey Malenkov
29  */
30 
31 import java.awt.Image;
32 import java.beans.BeanDescriptor;
33 import java.beans.BeanInfo;
34 import java.beans.EventSetDescriptor;
35 import java.beans.IntrospectionException;
36 import java.beans.Introspector;
37 import java.beans.MethodDescriptor;
38 import java.beans.PropertyDescriptor;
39 import java.util.Arrays;
40 import java.util.List;
41 
42 public class Test7193977 {
43 
44     private static final List<String> names = Arrays.asList("listType", "list", "value");
45 
main(String args[])46     public static void main(String args[]) {
47         for (String name : names) {
48             test(Abstract.class, name);
49             test(Concrete.class, name);
50         }
51     }
52 
test(Class<?> type, String name)53     private static void test(Class<?> type, String name) {
54         if (!Boolean.TRUE.equals(BeanUtils.getPropertyDescriptor(type, name).getValue("transient"))) {
55             throw new Error("property '" + name + "' is not transient");
56         }
57     }
58 
59     public static final class Concrete extends Abstract<String> {
60     }
61 
62     public static abstract class Abstract<T> {
63         private List<T> list;
64 
getList()65         public List<T> getList() {
66             return this.list;
67         }
68 
setList(List<T> list)69         public void setList(List<T> list) {
70             this.list = list;
71         }
72 
getValue(int index)73         public T getValue(int index) {
74             return (0 <= index) && (this.list != null) && (index < this.list.size())
75                     ? this.list.get(index)
76                     : null;
77         }
78 
setValue(int index, T value)79         public void setValue(int index, T value) {
80             if ((0 <= index) && (this.list != null)) {
81                 if (index == this.list.size()) {
82                     this.list.add(value);
83                 }
84                 else if (index < this.list.size()) {
85                     this.list.set(index, value);
86                 }
87             }
88         }
89 
getListType()90         public String getListType() {
91             return (this.list != null)
92                     ? this.list.getClass().getName()
93                     : null;
94         }
95 
setListType(String type)96         public void setListType(String type) throws Exception {
97             this.list = (type != null)
98                     ? (List<T>) Class.forName(type).newInstance()
99                     : null;
100         }
101     }
102 
103     public static final class ConcreteBeanInfo extends Wrapper {
ConcreteBeanInfo()104         public ConcreteBeanInfo() throws IntrospectionException {
105             super(Concrete.class);
106         }
107     }
108 
109     public static final class AbstractBeanInfo extends Wrapper {
AbstractBeanInfo()110         public AbstractBeanInfo() throws IntrospectionException {
111             super(Abstract.class);
112             for (PropertyDescriptor pd : getPropertyDescriptors()) {
113                 if (names.contains(pd.getName())) {
114                     pd.setValue("transient", Boolean.TRUE);
115                 }
116             }
117         }
118     }
119 
120     private static class Wrapper implements BeanInfo {
121         private final BeanInfo info;
122 
Wrapper(Class<?> type)123         Wrapper(Class<?> type) throws IntrospectionException {
124             this.info = Introspector.getBeanInfo(type, Introspector.IGNORE_IMMEDIATE_BEANINFO);
125         }
126 
getBeanDescriptor()127         public BeanDescriptor getBeanDescriptor() {
128             return this.info.getBeanDescriptor();
129         }
130 
getEventSetDescriptors()131         public EventSetDescriptor[] getEventSetDescriptors() {
132             return this.info.getEventSetDescriptors();
133         }
134 
getDefaultEventIndex()135         public int getDefaultEventIndex() {
136             return this.info.getDefaultEventIndex();
137         }
138 
getPropertyDescriptors()139         public PropertyDescriptor[] getPropertyDescriptors() {
140             return this.info.getPropertyDescriptors();
141         }
142 
getDefaultPropertyIndex()143         public int getDefaultPropertyIndex() {
144             return this.info.getDefaultPropertyIndex();
145         }
146 
getMethodDescriptors()147         public MethodDescriptor[] getMethodDescriptors() {
148             return this.info.getMethodDescriptors();
149         }
150 
getAdditionalBeanInfo()151         public BeanInfo[] getAdditionalBeanInfo() {
152             return this.info.getAdditionalBeanInfo();
153         }
154 
getIcon(int kind)155         public Image getIcon(int kind) {
156             return this.info.getIcon(kind);
157         }
158     }
159 }
160