001 /** 002 * Copyright 2005-2013 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 }