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 }