001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.beanutils.bugs;
018
019 import junit.framework.TestCase;
020 import org.apache.commons.beanutils.PropertyUtils;
021
022 import java.beans.PropertyDescriptor;
023
024
025 /*
026 * jdk's beans class do not work with covariant returns & generics.
027 * <p>
028 * See https://issues.apache.org/jira/browse/BEANUTILS-340
029 * See http://bugs.sun.com/view_bug.do?bug_id=6528714
030 * </p>
031 */
032 public class Jira340TestCase extends TestCase {
033
034 public void testStub() {}
035
036 /* these tests require java 5+ language level to compile and execute */
037
038 public void testCovariantReturnPropertyUtils() throws Throwable {
039 assertEquals(InnerBean.class, PropertyUtils.getPropertyType(new Bean(), "innerBean"));
040 final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new Bean(), "innerBean");
041 assertEquals(InnerBean.class, d.getPropertyType());
042 assertEquals(InnerBean.class, d.getReadMethod().getReturnType());
043 }
044
045 //this method will fail due to a java Introspector api bug
046 public void failing_testCovariantReturnIntrospector() throws Throwable {
047 java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(Bean.class);
048 final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
049 for (int i = 0; i < descriptors.length; i ++) {
050 if ("innerBean".equals(descriptors[i].getName())) {
051 assertEquals(InnerBean.class, descriptors[i].getPropertyType());
052 assertEquals(InnerBean.class, descriptors[i].getReadMethod().getReturnType());
053 }
054 }
055 }
056
057 public void testGenericReadWritePropertyUtils() throws Throwable {
058 assertEquals(String.class, PropertyUtils.getPropertyType(new ReadWriteNamedBean(), "name"));
059
060 final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new ReadWriteNamedBean(), "name");
061 assertEquals(String.class, d.getPropertyType());
062 assertEquals(String.class, d.getReadMethod().getReturnType());
063 assertEquals(String.class, d.getWriteMethod().getParameterTypes()[0]);
064 }
065
066 //this method will fail due to a java Introspector api bug
067 public void failing_testGenericReadWriteIntrospector() throws Throwable {
068 java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(ReadWriteNamedBean.class);
069 final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
070 for (int i = 0; i < descriptors.length; i ++) {
071 if ("name".equals(descriptors[i].getName())) {
072 assertEquals(String.class, descriptors[i].getPropertyType());
073 assertEquals(String.class, descriptors[i].getReadMethod().getReturnType());
074 assertEquals(String.class, descriptors[i].getWriteMethod().getParameterTypes()[0]);
075 }
076 }
077 }
078
079 public void testGenericWritePropertyUtils() throws Throwable {
080 assertEquals(String.class, PropertyUtils.getPropertyType(new WriteNamedBean(), "name"));
081
082 final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new WriteNamedBean(), "name");
083 assertEquals(String.class, d.getPropertyType());
084 assertEquals(String.class, d.getWriteMethod().getParameterTypes()[0]);
085 }
086
087 //this method will fail due to a java Introspector api bug
088 public void failing_testGenericWriteIntrospector() throws Throwable {
089 java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(WriteNamedBean.class);
090 final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
091 for (int i = 0; i < descriptors.length; i ++) {
092 if ("name".equals(descriptors[i].getName())) {
093 assertEquals(String.class, descriptors[i].getPropertyType());
094 assertEquals(String.class, descriptors[i].getWriteMethod().getParameterTypes()[0]);
095 }
096 }
097 }
098
099 public void testGenericReadPropertyUtils() throws Throwable {
100 assertEquals(String.class, PropertyUtils.getPropertyType(new ReadNamedBean(), "name"));
101
102 final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new ReadNamedBean(), "name");
103 assertEquals(String.class, d.getPropertyType());
104 assertEquals(String.class, d.getReadMethod().getReturnType());
105 }
106
107 //this method will fail due to a java Introspector api bug
108 public void failing_testGenericReadIntrospector() throws Throwable {
109 java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(WriteNamedBean.class);
110 final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
111 for (int i = 0; i < descriptors.length; i ++) {
112 if ("name".equals(descriptors[i].getName())) {
113 assertEquals(String.class, descriptors[i].getPropertyType());
114 assertEquals(String.class, descriptors[i].getReadMethod().getReturnType());
115 }
116 }
117 }
118
119 public void testGenericWriteOverloadInheritPropertyUtils() throws Throwable {
120 //can't really assert a specific type b/c it's non-deterministic - just want to make sure things don't blow up
121 assertNotNull(PropertyUtils.getPropertyType(new WriteOverloadNamedBeanInherit(), "name"));
122
123 final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new WriteOverloadNamedBeanInherit(), "name");
124 assertNotNull(d.getPropertyType());
125 assertNotNull(d.getWriteMethod().getParameterTypes()[0]);
126 }
127
128 //this method will fail due to a java Introspector api bug
129 public void testGenericWriteOverloadInheritIntrospector() throws Throwable {
130 //can't really assert a specific type b/c it's non-deterministic - just want to make sure things don't blow up
131 java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(WriteOverloadNamedBeanInherit.class);
132 final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
133 for (int i = 0; i < descriptors.length; i ++) {
134 if ("name".equals(descriptors[i].getName())) {
135 assertNotNull(descriptors[i].getPropertyType());
136 assertNotNull(descriptors[i].getWriteMethod().getParameterTypes()[0]);
137 }
138 }
139 }
140
141 public void testGenericWriteOverloadNonInheritPropertyUtils() throws Throwable {
142 //can't really assert a specific type b/c it's non-deterministic - just want to make sure things don't blow up
143 assertNotNull(PropertyUtils.getPropertyType(new WriteOverloadNamedBeanNonInherit(), "name"));
144
145 final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new WriteOverloadNamedBeanNonInherit(), "name");
146 assertNotNull(d.getPropertyType());
147 assertNotNull(d.getWriteMethod().getParameterTypes()[0]);
148 }
149
150 //this method will fail due to a java Introspector api bug
151 public void testGenericWriteOverloadNonInheritIntrospector() throws Throwable {
152 //can't really assert a specific type b/c it's non-deterministic - just want to make sure things don't blow up
153 java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(WriteOverloadNamedBeanNonInherit.class);
154 final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
155 for (int i = 0; i < descriptors.length; i ++) {
156 if ("name".equals(descriptors[i].getName())) {
157 assertNotNull(descriptors[i].getPropertyType());
158 assertNotNull(descriptors[i].getWriteMethod().getParameterTypes()[0]);
159 }
160 }
161 }
162
163 public void testVisibilityBridge() throws Throwable {
164 assertEquals(String.class, PropertyUtils.getPropertyType(new PublicClass(), "foo"));
165 }
166
167 //example 1 start
168 static class Bean implements Beanable {
169 private InnerBean innerBean = new InnerBean();
170
171 public InnerBean getInnerBean() {
172 return innerBean;
173 }
174 }
175
176 static interface Beanable {
177 InnerBeanable getInnerBean();
178 }
179
180 static class InnerBean implements InnerBeanable {
181 }
182
183 static interface InnerBeanable {
184 }
185 //example 1 end
186
187 //example 2/3/4 start
188 static interface ReadNamed<T> {
189 T getName();
190 }
191
192 static interface WriteNamed<T> {
193 void setName(T t);
194 }
195
196 static class ReadWriteNamedBean implements ReadNamed<String>, WriteNamed<String> {
197 private String myName;
198
199 public String getName() {
200 return myName;
201 }
202
203 public void setName(String name) {
204 myName = name;
205 }
206 }
207
208 static class WriteNamedBean implements WriteNamed<String> {
209 private String myName;
210 public void setName(String name) {
211 myName = name;
212 }
213 }
214
215 static class ReadNamedBean implements ReadNamed<String> {
216 private final String myName = "foo";
217 public String getName() {
218 return myName;
219 }
220 }
221 //example 2/3/4 end
222
223
224 //example 5 start
225 //not using covariant return but still generating a bridge method on later java versions
226 static class PackagePrivateClass {
227 public String getFoo() { return null; }
228 }
229 public static class PublicClass extends PackagePrivateClass { }
230 //example 5 end
231
232 //example 6 start
233 static class WriteOverloadNamedBeanInherit implements WriteNamed<String> {
234 private String myName;
235
236 public void setName(String s) {
237 myName = s;
238 }
239
240 public void setName(CharSequence s) {
241 myName = s.toString();
242 }
243 }
244 //example 6 end
245
246 //example 7 start
247 static class WriteOverloadNamedBeanNonInherit implements WriteNamed<String> {
248 private String myName;
249
250 public void setName(String s) {
251 myName = s;
252 }
253
254 public void setName(Number s) {
255 myName = s.toString();
256 }
257 }
258 //example 7 end
259 }