001 /**
002 * Copyright 2005-2012 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.apache.commons.beanutils.bugs;
017
018 import junit.framework.TestCase;
019 import org.apache.commons.beanutils.PropertyUtils;
020
021 import java.beans.PropertyDescriptor;
022
023
024 /*
025 * jdk's beans class do not work with covariant returns & generics.
026 * <p>
027 * See https://issues.apache.org/jira/browse/BEANUTILS-340
028 * See http://bugs.sun.com/view_bug.do?bug_id=6528714
029 * </p>
030 */
031 public class Jira340TestCase extends TestCase {
032
033 public void testStub() {}
034
035 /* these tests require java 5+ language level to compile and execute */
036
037 public void testCovariantReturnPropertyUtils() throws Throwable {
038 assertEquals(InnerBean.class, PropertyUtils.getPropertyType(new Bean(), "innerBean"));
039 final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new Bean(), "innerBean");
040 assertEquals(InnerBean.class, d.getPropertyType());
041 assertEquals(InnerBean.class, d.getReadMethod().getReturnType());
042 }
043
044 //this method will fail due to a java Introspector api bug
045 public void failing_testCovariantReturnIntrospector() throws Throwable {
046 java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(Bean.class);
047 final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
048 for (int i = 0; i < descriptors.length; i ++) {
049 if ("innerBean".equals(descriptors[i].getName())) {
050 assertEquals(InnerBean.class, descriptors[i].getPropertyType());
051 assertEquals(InnerBean.class, descriptors[i].getReadMethod().getReturnType());
052 }
053 }
054 }
055
056 public void testGenericReadWritePropertyUtils() throws Throwable {
057 assertEquals(String.class, PropertyUtils.getPropertyType(new ReadWriteNamedBean(), "name"));
058
059 final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new ReadWriteNamedBean(), "name");
060 assertEquals(String.class, d.getPropertyType());
061 assertEquals(String.class, d.getReadMethod().getReturnType());
062 assertEquals(String.class, d.getWriteMethod().getParameterTypes()[0]);
063 }
064
065 //this method will fail due to a java Introspector api bug
066 public void failing_testGenericReadWriteIntrospector() throws Throwable {
067 java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(ReadWriteNamedBean.class);
068 final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
069 for (int i = 0; i < descriptors.length; i ++) {
070 if ("name".equals(descriptors[i].getName())) {
071 assertEquals(String.class, descriptors[i].getPropertyType());
072 assertEquals(String.class, descriptors[i].getReadMethod().getReturnType());
073 assertEquals(String.class, descriptors[i].getWriteMethod().getParameterTypes()[0]);
074 }
075 }
076 }
077
078 public void testGenericWritePropertyUtils() throws Throwable {
079 assertEquals(String.class, PropertyUtils.getPropertyType(new WriteNamedBean(), "name"));
080
081 final PropertyDescriptor d = PropertyUtils.getPropertyDescriptor(new WriteNamedBean(), "name");
082 assertEquals(String.class, d.getPropertyType());
083 assertEquals(String.class, d.getWriteMethod().getParameterTypes()[0]);
084 }
085
086 //this method will fail due to a java Introspector api bug
087 public void failing_testGenericWriteIntrospector() throws Throwable {
088 java.beans.BeanInfo bi = java.beans.Introspector.getBeanInfo(WriteNamedBean.class);
089 final PropertyDescriptor[] descriptors = bi.getPropertyDescriptors();
090 for (int i = 0; i < descriptors.length; i ++) {
091 if ("name".equals(descriptors[i].getName())) {
092 assertEquals(String.class, descriptors[i].getPropertyType());
093 assertEquals(String.class, descriptors[i].getWriteMethod().getParameterTypes()[0]);
094 }
095 }
096 }
097
098 public void testGenericReadPropertyUtils() throws Throwable {
099 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 }