View Javadoc

1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.beanutils.bugs;
17  
18  import junit.framework.TestCase;
19  import org.apache.commons.beanutils.PropertyUtils;
20  
21  import java.beans.PropertyDescriptor;
22  
23  
24  /*
25   * jdk's beans class do not work with covariant returns & generics.
26   * <p>
27   * See https://issues.apache.org/jira/browse/BEANUTILS-340
28   * See http://bugs.sun.com/view_bug.do?bug_id=6528714
29   * </p>
30   */
31  public class Jira340TestCase extends TestCase {
32  
33      public void testStub() {}
34  
35      /* these tests require java 5+ language level to compile and execute */
36  
37      public void testCovariantReturnPropertyUtils() throws Throwable {
38          assertEquals(InnerBean.class, PropertyUtils.getPropertyType(new Bean(), "innerBean"));
39          final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new Bean(), "innerBean");
40          assertEquals(InnerBean.class, d.getPropertyType());
41          assertEquals(InnerBean.class, d.getReadMethod().getReturnType());
42      }
43  
44      //this method will fail due to a java Introspector api bug
45      public void failing_testCovariantReturnIntrospector() throws Throwable {
46          java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(Bean.class);
47          final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
48          for (int i = 0; i < descriptors.length; i ++) {
49              if ("innerBean".equals(descriptors[i].getName())) {
50                  assertEquals(InnerBean.class, descriptors[i].getPropertyType());
51                  assertEquals(InnerBean.class, descriptors[i].getReadMethod().getReturnType());
52              }
53          }
54      }
55  
56      public void testGenericReadWritePropertyUtils() throws Throwable {
57          assertEquals(String.class, PropertyUtils.getPropertyType(new ReadWriteNamedBean(), "name"));
58  
59          final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new ReadWriteNamedBean(), "name");
60          assertEquals(String.class, d.getPropertyType());
61          assertEquals(String.class, d.getReadMethod().getReturnType());
62          assertEquals(String.class, d.getWriteMethod().getParameterTypes()[0]);
63      }
64  
65      //this method will fail due to a java Introspector api bug
66      public void failing_testGenericReadWriteIntrospector() throws Throwable {
67          java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(ReadWriteNamedBean.class);
68          final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
69          for (int i = 0; i < descriptors.length; i ++) {
70              if ("name".equals(descriptors[i].getName())) {
71                  assertEquals(String.class, descriptors[i].getPropertyType());
72                  assertEquals(String.class, descriptors[i].getReadMethod().getReturnType());
73                  assertEquals(String.class, descriptors[i].getWriteMethod().getParameterTypes()[0]);
74              }
75          }
76      }
77  
78      public void testGenericWritePropertyUtils() throws Throwable {
79          assertEquals(String.class, PropertyUtils.getPropertyType(new WriteNamedBean(), "name"));
80  
81          final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new WriteNamedBean(), "name");
82          assertEquals(String.class, d.getPropertyType());
83          assertEquals(String.class, d.getWriteMethod().getParameterTypes()[0]);
84      }
85  
86      //this method will fail due to a java Introspector api bug
87      public void failing_testGenericWriteIntrospector() throws Throwable {
88          java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(WriteNamedBean.class);
89          final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
90          for (int i = 0; i < descriptors.length; i ++) {
91              if ("name".equals(descriptors[i].getName())) {
92                  assertEquals(String.class, descriptors[i].getPropertyType());
93                  assertEquals(String.class, descriptors[i].getWriteMethod().getParameterTypes()[0]);
94              }
95          }
96      }
97  
98      public void testGenericReadPropertyUtils() throws Throwable {
99          assertEquals(String.class, PropertyUtils.getPropertyType(new ReadNamedBean(), "name"));
100 
101         final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new ReadNamedBean(), "name");
102         assertEquals(String.class, d.getPropertyType());
103         assertEquals(String.class, d.getReadMethod().getReturnType());
104     }
105 
106     //this method will fail due to a java Introspector api bug
107     public void failing_testGenericReadIntrospector() throws Throwable {
108         java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(WriteNamedBean.class);
109         final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
110         for (int i = 0; i < descriptors.length; i ++) {
111             if ("name".equals(descriptors[i].getName())) {
112                 assertEquals(String.class, descriptors[i].getPropertyType());
113                 assertEquals(String.class, descriptors[i].getReadMethod().getReturnType());
114             }
115         }
116     }
117 
118     public void testGenericWriteOverloadInheritPropertyUtils() throws Throwable {
119         //can't really assert a specific type b/c it's non-deterministic - just want to make sure things don't blow up
120         assertNotNull(PropertyUtils.getPropertyType(new WriteOverloadNamedBeanInherit(), "name"));
121 
122         final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new WriteOverloadNamedBeanInherit(), "name");
123         assertNotNull(d.getPropertyType());
124         assertNotNull(d.getWriteMethod().getParameterTypes()[0]);
125     }
126 
127     //this method will fail due to a java Introspector api bug
128     public void testGenericWriteOverloadInheritIntrospector() throws Throwable {
129         //can't really assert a specific type b/c it's non-deterministic - just want to make sure things don't blow up
130         java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(WriteOverloadNamedBeanInherit.class);
131         final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
132         for (int i = 0; i < descriptors.length; i ++) {
133             if ("name".equals(descriptors[i].getName())) {
134                 assertNotNull(descriptors[i].getPropertyType());
135                 assertNotNull(descriptors[i].getWriteMethod().getParameterTypes()[0]);
136             }
137         }
138     }
139 
140     public void testGenericWriteOverloadNonInheritPropertyUtils() throws Throwable {
141         //can't really assert a specific type b/c it's non-deterministic - just want to make sure things don't blow up
142         assertNotNull(PropertyUtils.getPropertyType(new WriteOverloadNamedBeanNonInherit(), "name"));
143 
144         final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new WriteOverloadNamedBeanNonInherit(), "name");
145         assertNotNull(d.getPropertyType());
146         assertNotNull(d.getWriteMethod().getParameterTypes()[0]);
147     }
148 
149     //this method will fail due to a java Introspector api bug
150     public void testGenericWriteOverloadNonInheritIntrospector() throws Throwable {
151         //can't really assert a specific type b/c it's non-deterministic - just want to make sure things don't blow up
152         java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(WriteOverloadNamedBeanNonInherit.class);
153         final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
154         for (int i = 0; i < descriptors.length; i ++) {
155             if ("name".equals(descriptors[i].getName())) {
156                 assertNotNull(descriptors[i].getPropertyType());
157                 assertNotNull(descriptors[i].getWriteMethod().getParameterTypes()[0]);
158             }
159         }
160     }
161 
162     public void testVisibilityBridge() throws Throwable {
163         assertEquals(String.class, PropertyUtils.getPropertyType(new PublicClass(), "foo"));
164     }
165 
166     //example 1 start
167     static class Bean implements Beanable {
168         private InnerBean innerBean = new InnerBean();
169 
170         public InnerBean getInnerBean() {
171             return innerBean;
172         }
173     }
174 
175     static interface Beanable {
176         InnerBeanable getInnerBean();
177     }
178 
179     static class InnerBean implements InnerBeanable {
180     }
181 
182     static interface InnerBeanable {
183     }
184     //example 1 end
185 
186     //example 2/3/4 start
187     static interface ReadNamed<T> {
188         T getName();
189     }
190 
191     static interface WriteNamed<T> {
192         void setName(T t);
193     }
194 
195     static class ReadWriteNamedBean implements ReadNamed<String>, WriteNamed<String> {
196         private String myName;
197 
198         public String getName() {
199             return myName;
200         }
201 
202         public void setName(String name) {
203             myName = name;
204         }
205     }
206 
207     static class WriteNamedBean implements WriteNamed<String> {
208         private String myName;
209         public void setName(String name) {
210             myName = name;
211         }
212     }
213 
214     static class ReadNamedBean implements ReadNamed<String> {
215         private final String myName = "foo";
216         public String getName() {
217             return myName;
218         }
219     }
220     //example 2/3/4 end
221 
222 
223     //example 5 start
224     //not using covariant return but still generating a bridge method on later java versions
225     static class PackagePrivateClass {
226         public String getFoo() { return null; }
227     }
228     public static class PublicClass extends PackagePrivateClass { }
229     //example 5 end
230 
231     //example 6 start
232     static class WriteOverloadNamedBeanInherit implements WriteNamed<String> {
233         private String myName;
234 
235         public void setName(String s) {
236             myName = s;
237         }
238 
239         public void setName(CharSequence s) {
240             myName = s.toString();
241         }
242     }
243     //example 6 end
244 
245     //example 7 start
246     static class WriteOverloadNamedBeanNonInherit implements WriteNamed<String> {
247         private String myName;
248 
249         public void setName(String s) {
250             myName = s;
251         }
252 
253         public void setName(Number s) {
254             myName = s.toString();
255         }
256     }
257     //example 7 end
258 }