// Copyright (c) 2003-present, Jodd Team (http://jodd.org) // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. package jodd.introspector; import jodd.util.ClassUtil; import org.junit.Test; import java.lang.reflect.Method; import java.util.List; import java.util.Map; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; public class IntrospectorGenericsTest { public static class MethodParameterType<A> { List<A> f; List f2; Map<String, A>f3; List<Long> f4; <T extends List<T>> void m(A a, String p1, T p2, List<?> p3, List<T> p4) { } <T extends List<T>> List<T> m2(A a, String p1, T p2, List<?> p3, List<T> p4) { return null; } <T extends List<T>> List<A> m3(A a, String p1, T p2, List<?> p3, List<T> p4) { return null; } List<Byte> m4(List<Long> list) {return null;} List<A> m5(List<A> list) {return null;} } public static class Foo extends MethodParameterType<Integer> {} @Test public void testFields() throws NoSuchFieldException { ClassDescriptor cd = ClassIntrospector.lookup(MethodParameterType.class); assertEquals(MethodParameterType.class, cd.getType()); assertEquals(4, cd.getAllFieldDescriptors().length); FieldDescriptor[] fs = cd.getAllFieldDescriptors(); int p = 0; for (FieldDescriptor f : fs) { if (f.isPublic()) { p++; } } assertEquals(0, p); FieldDescriptor fd = cd.getFieldDescriptor("f", true); FieldDescriptor fd2 = cd.getFieldDescriptor("f2", true); FieldDescriptor fd3 = cd.getFieldDescriptor("f3", true); FieldDescriptor fd4 = cd.getFieldDescriptor("f4", true); assertEquals(List.class, fd.getRawType()); assertEquals(Object.class, fd.getRawComponentType()); assertEquals(List.class, fd2.getRawType()); assertNull(fd2.getRawComponentType()); assertEquals(Map.class, fd3.getRawType()); assertEquals(Object.class, fd3.getRawComponentType()); assertEquals(List.class, fd4.getRawType()); assertEquals(Long.class, fd4.getRawComponentType()); // impl cd = ClassIntrospector.lookup(Foo.class); fd = cd.getFieldDescriptor("f", true); fd2 = cd.getFieldDescriptor("f2", true); fd3 = cd.getFieldDescriptor("f3", true); assertEquals(List.class, fd.getRawType()); assertEquals(Integer.class, fd.getRawComponentType()); assertEquals(List.class, fd2.getRawType()); assertNull(fd2.getRawComponentType()); assertEquals(Map.class, fd3.getRawType()); assertEquals(Integer.class, fd3.getRawComponentType()); assertEquals(String.class, ClassUtil.getComponentTypes(fd3.getField().getGenericType(), cd.getType())[0]); } @Test public void testMethods() throws NoSuchMethodException { ClassDescriptor cd = ClassIntrospector.lookup(MethodParameterType.class); assertEquals(MethodParameterType.class, cd.getType()); assertEquals(5, cd.getAllMethodDescriptors().length); MethodDescriptor[] mds = cd.getAllMethodDescriptors(); int mc = 0; for (MethodDescriptor md : mds) { if (md.isPublic()) mc++; } assertEquals(0, mc); Class[] params = new Class[] {Object.class, String.class, List.class, List.class, List.class}; Method m = MethodParameterType.class.getDeclaredMethod("m", params); assertNotNull(m); Method m2 = cd.getMethodDescriptor("m", params, true).getMethod(); assertNotNull(m2); assertEquals(m, m2); MethodDescriptor md1 = cd.getMethodDescriptor("m", params, true); assertNotNull(md1); assertEquals(m, md1.getMethod()); assertArrayEquals(params, md1.getRawParameterTypes()); assertEquals(void.class, md1.getRawReturnType()); assertNull(md1.getRawReturnComponentType()); MethodDescriptor md2 = cd.getMethodDescriptor("m2", params, true); assertNotNull(md2); assertArrayEquals(params, md2.getRawParameterTypes()); assertEquals(List.class, md2.getRawReturnType()); assertEquals(List.class, md2.getRawReturnComponentType()); MethodDescriptor md3 = cd.getMethodDescriptor("m3", params, true); assertNotNull(md3); assertArrayEquals(params, md3.getRawParameterTypes()); assertEquals(List.class, md3.getRawReturnType()); assertEquals(Object.class, md3.getRawReturnComponentType()); MethodDescriptor md4 = cd.getMethodDescriptor("m4", new Class[] {List.class}, true); assertNotNull(md4); assertArrayEquals(new Class[] {List.class}, md4.getRawParameterTypes()); assertEquals(List.class, md4.getRawReturnType()); assertEquals(Byte.class, md4.getRawReturnComponentType()); assertEquals(List.class, md4.getSetterRawType()); assertEquals(Long.class, md4.getSetterRawComponentType()); MethodDescriptor md5 = cd.getMethodDescriptor("m5", new Class[] {List.class}, true); assertNotNull(md5); assertArrayEquals(new Class[] {List.class}, md5.getRawParameterTypes()); assertEquals(List.class, md5.getRawReturnType()); assertEquals(Object.class, md5.getRawReturnComponentType()); assertEquals(List.class, md5.getSetterRawType()); assertEquals(Object.class, md5.getSetterRawComponentType()); // impl Class[] params2 = new Class[] {Integer.class, String.class, List.class, List.class, List.class}; ClassDescriptor cd1 = ClassIntrospector.lookup(Foo.class); assertEquals(0, Foo.class.getDeclaredMethods().length); MethodDescriptor[] allm = cd1.getAllMethodDescriptors(); assertEquals(5, allm.length); md3 = cd1.getMethodDescriptor("m", params, true); assertNotNull(md3); assertArrayEquals(params2, md3.getRawParameterTypes()); md3 = cd1.getMethodDescriptor("m3", params, true); assertNotNull(md3); assertArrayEquals(params2, md3.getRawParameterTypes()); assertEquals(List.class, md3.getRawReturnType()); assertEquals(Integer.class, md3.getRawReturnComponentType()); md5 = cd1.getMethodDescriptor("m5", new Class[] {List.class}, true); assertNotNull(md5); assertArrayEquals(new Class[] {List.class}, md5.getRawParameterTypes()); assertEquals(List.class, md5.getRawReturnType()); assertEquals(Integer.class, md5.getRawReturnComponentType()); assertEquals(List.class, md5.getSetterRawType()); assertEquals(Integer.class, md5.getSetterRawComponentType()); } }