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