View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.beanutils.bugs;
18  
19  import junit.framework.TestCase;
20  import org.apache.commons.beanutils.PropertyUtils;
21  
22  import java.beans.PropertyDescriptor;
23  
24  
25  /**
26   * jdk's beans class do not work with covariant returns & generics.
27   * <p>
28   * See https://issues.apache.org/jira/browse/BEANUTILS-340
29   * See http://bugs.sun.com/view_bug.do?bug_id=6528714
30   * </p>
31   */
32  public class Jira340TestCase extends TestCase {
33  
34      public void testStub() {}
35  
36      /* these tests require java 5+ language level to compile and execute
37  
38      public void testCovariantReturnPropertyUtils() throws Throwable {
39          assertEquals(InnerBean.class, PropertyUtils.getPropertyType(new Bean(), "innerBean"));
40          final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new Bean(), "innerBean");
41          assertEquals(InnerBean.class, d.getPropertyType());
42          assertEquals(InnerBean.class, d.getReadMethod().getReturnType());
43      }
44  
45      //this method will fail due to a java Introspector api bug
46      public void failing_testCovariantReturnIntrospector() throws Throwable {
47          java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(Bean.class);
48          final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
49          for (int i = 0; i < descriptors.length; i ++) {
50              if ("innerBean".equals(descriptors[i].getName())) {
51                  assertEquals(InnerBean.class, descriptors[i].getPropertyType());
52                  assertEquals(InnerBean.class, descriptors[i].getReadMethod().getReturnType());
53              }
54          }
55      }
56  
57      public void testGenericReadWritePropertyUtils() throws Throwable {
58          assertEquals(String.class, PropertyUtils.getPropertyType(new ReadWriteNamedBean(), "name"));
59  
60          final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new ReadWriteNamedBean(), "name");
61          assertEquals(String.class, d.getPropertyType());
62          assertEquals(String.class, d.getReadMethod().getReturnType());
63          assertEquals(String.class, d.getWriteMethod().getParameterTypes()[0]);
64      }
65  
66      //this method will fail due to a java Introspector api bug
67      public void failing_testGenericReadWriteIntrospector() throws Throwable {
68          java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(ReadWriteNamedBean.class);
69          final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
70          for (int i = 0; i < descriptors.length; i ++) {
71              if ("name".equals(descriptors[i].getName())) {
72                  assertEquals(String.class, descriptors[i].getPropertyType());
73                  assertEquals(String.class, descriptors[i].getReadMethod().getReturnType());
74                  assertEquals(String.class, descriptors[i].getWriteMethod().getParameterTypes()[0]);
75              }
76          }
77      }
78  
79      public void testGenericWritePropertyUtils() throws Throwable {
80          assertEquals(String.class, PropertyUtils.getPropertyType(new WriteNamedBean(), "name"));
81  
82          final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new WriteNamedBean(), "name");
83          assertEquals(String.class, d.getPropertyType());
84          assertEquals(String.class, d.getWriteMethod().getParameterTypes()[0]);
85      }
86  
87      //this method will fail due to a java Introspector api bug
88      public void failing_testGenericWriteIntrospector() throws Throwable {
89          java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(WriteNamedBean.class);
90          final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
91          for (int i = 0; i < descriptors.length; i ++) {
92              if ("name".equals(descriptors[i].getName())) {
93                  assertEquals(String.class, descriptors[i].getPropertyType());
94                  assertEquals(String.class, descriptors[i].getWriteMethod().getParameterTypes()[0]);
95              }
96          }
97      }
98  
99      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     */
260 }