blob: 66477ea20ba00749cf83f5a5c5d22342e0882f9f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.lang3.reflect;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.reflect.testbed.Foo;
import org.apache.commons.lang3.reflect.testbed.GenericParent;
import org.apache.commons.lang3.reflect.testbed.GenericTypeHolder;
import org.apache.commons.lang3.reflect.testbed.StringParameterizedChild;
import org.junit.Assert;
import org.junit.Test;
/**
* Test TypeUtils
*/
@SuppressWarnings({ "unchecked", "unused" , "rawtypes" })
//raw types, where used, are used purposely
public class TypeUtilsTest<B> {
public interface This<K, V> {
}
public class That<K, V> implements This<K, V> {
}
public interface And<K, V> extends This<Number, Number> {
}
public class The<K, V> extends That<Number, Number> implements And<String, String> {
}
public class Other<T> implements This<String, T> {
}
public class Thing<Q> extends Other<B> {
}
public class Tester implements This<String, B> {
}
public This<String, String> dis;
public That<String, String> dat;
public The<String, String> da;
public Other<String> uhder;
public Thing ding;
public TypeUtilsTest<String>.Tester tester;
public Tester tester2;
public TypeUtilsTest<String>.That<String, String> dat2;
public TypeUtilsTest<Number>.That<String, String> dat3;
public Comparable<? extends Integer>[] intWildcardComparable;
public static Comparable<String> stringComparable;
public static Comparable<URI> uriComparable;
public static Comparable<Integer> intComparable;
public static Comparable<Long> longComparable;
public static Comparable<?> wildcardComparable;
public static URI uri;
public void dummyMethod(final List list0, final List<Object> list1, final List<?> list2,
final List<? super Object> list3, final List<String> list4, final List<? extends String> list5,
final List<? super String> list6, final List[] list7, final List<Object>[] list8, final List<?>[] list9,
final List<? super Object>[] list10, final List<String>[] list11, final List<? extends String>[] list12,
final List<? super String>[] list13) {
}
@SuppressWarnings("boxing") // deliberately used here
@Test
public void testIsAssignable() throws SecurityException, NoSuchMethodException,
NoSuchFieldException {
List list0 = null;
List<Object> list1 = null;
List<?> list2 = null;
List<? super Object> list3 = null;
List<String> list4 = null;
List<? extends String> list5 = null;
List<? super String> list6 = null;
List[] list7 = null;
List<Object>[] list8 = null;
List<?>[] list9 = null;
List<? super Object>[] list10 = null;
List<String>[] list11 = null;
List<? extends String>[] list12 = null;
List<? super String>[] list13;
final Class<?> clazz = getClass();
final Method method = clazz.getMethod("dummyMethod", List.class, List.class, List.class,
List.class, List.class, List.class, List.class, List[].class, List[].class,
List[].class, List[].class, List[].class, List[].class, List[].class);
final Type[] types = method.getGenericParameterTypes();
// list0 = list0;
delegateBooleanAssertion(types, 0, 0, true);
list1 = list0;
delegateBooleanAssertion(types, 0, 1, true);
list0 = list1;
delegateBooleanAssertion(types, 1, 0, true);
list2 = list0;
delegateBooleanAssertion(types, 0, 2, true);
list0 = list2;
delegateBooleanAssertion(types, 2, 0, true);
list3 = list0;
delegateBooleanAssertion(types, 0, 3, true);
list0 = list3;
delegateBooleanAssertion(types, 3, 0, true);
list4 = list0;
delegateBooleanAssertion(types, 0, 4, true);
list0 = list4;
delegateBooleanAssertion(types, 4, 0, true);
list5 = list0;
delegateBooleanAssertion(types, 0, 5, true);
list0 = list5;
delegateBooleanAssertion(types, 5, 0, true);
list6 = list0;
delegateBooleanAssertion(types, 0, 6, true);
list0 = list6;
delegateBooleanAssertion(types, 6, 0, true);
// list1 = list1;
delegateBooleanAssertion(types, 1, 1, true);
list2 = list1;
delegateBooleanAssertion(types, 1, 2, true);
list1 = (List<Object>) list2;
delegateBooleanAssertion(types, 2, 1, false);
list3 = list1;
delegateBooleanAssertion(types, 1, 3, true);
list1 = (List<Object>) list3;
delegateBooleanAssertion(types, 3, 1, false);
// list4 = list1;
delegateBooleanAssertion(types, 1, 4, false);
// list1 = list4;
delegateBooleanAssertion(types, 4, 1, false);
// list5 = list1;
delegateBooleanAssertion(types, 1, 5, false);
// list1 = list5;
delegateBooleanAssertion(types, 5, 1, false);
list6 = list1;
delegateBooleanAssertion(types, 1, 6, true);
list1 = (List<Object>) list6;
delegateBooleanAssertion(types, 6, 1, false);
// list2 = list2;
delegateBooleanAssertion(types, 2, 2, true);
list2 = list3;
delegateBooleanAssertion(types, 2, 3, false);
list2 = list4;
delegateBooleanAssertion(types, 3, 2, true);
list3 = (List<? super Object>) list2;
delegateBooleanAssertion(types, 2, 4, false);
list2 = list5;
delegateBooleanAssertion(types, 4, 2, true);
list4 = (List<String>) list2;
delegateBooleanAssertion(types, 2, 5, false);
list2 = list6;
delegateBooleanAssertion(types, 5, 2, true);
list5 = (List<? extends String>) list2;
delegateBooleanAssertion(types, 2, 6, false);
// list3 = list3;
delegateBooleanAssertion(types, 6, 2, true);
list6 = (List<? super String>) list2;
delegateBooleanAssertion(types, 3, 3, true);
// list4 = list3;
delegateBooleanAssertion(types, 3, 4, false);
// list3 = list4;
delegateBooleanAssertion(types, 4, 3, false);
// list5 = list3;
delegateBooleanAssertion(types, 3, 5, false);
// list3 = list5;
delegateBooleanAssertion(types, 5, 3, false);
list6 = list3;
delegateBooleanAssertion(types, 3, 6, true);
list3 = (List<? super Object>) list6;
delegateBooleanAssertion(types, 6, 3, false);
// list4 = list4;
delegateBooleanAssertion(types, 4, 4, true);
list5 = list4;
delegateBooleanAssertion(types, 4, 5, true);
list4 = (List<String>) list5;
delegateBooleanAssertion(types, 5, 4, false);
list6 = list4;
delegateBooleanAssertion(types, 4, 6, true);
list4 = (List<String>) list6;
delegateBooleanAssertion(types, 6, 4, false);
// list5 = list5;
delegateBooleanAssertion(types, 5, 5, true);
list6 = (List<? super String>) list5;
delegateBooleanAssertion(types, 5, 6, false);
list5 = (List<? extends String>) list6;
delegateBooleanAssertion(types, 6, 5, false);
// list6 = list6;
delegateBooleanAssertion(types, 6, 6, true);
// list7 = list7;
delegateBooleanAssertion(types, 7, 7, true);
list8 = list7;
delegateBooleanAssertion(types, 7, 8, true);
list7 = list8;
delegateBooleanAssertion(types, 8, 7, true);
list9 = list7;
delegateBooleanAssertion(types, 7, 9, true);
list7 = list9;
delegateBooleanAssertion(types, 9, 7, true);
list10 = list7;
delegateBooleanAssertion(types, 7, 10, true);
list7 = list10;
delegateBooleanAssertion(types, 10, 7, true);
list11 = list7;
delegateBooleanAssertion(types, 7, 11, true);
list7 = list11;
delegateBooleanAssertion(types, 11, 7, true);
list12 = list7;
delegateBooleanAssertion(types, 7, 12, true);
list7 = list12;
delegateBooleanAssertion(types, 12, 7, true);
list13 = list7;
delegateBooleanAssertion(types, 7, 13, true);
list7 = list13;
delegateBooleanAssertion(types, 13, 7, true);
// list8 = list8;
delegateBooleanAssertion(types, 8, 8, true);
list9 = list8;
delegateBooleanAssertion(types, 8, 9, true);
list8 = (List<Object>[]) list9;
delegateBooleanAssertion(types, 9, 8, false);
list10 = list8;
delegateBooleanAssertion(types, 8, 10, true);
list8 = (List<Object>[]) list10; // NOTE cast is required by Sun Java, but not by Eclipse
delegateBooleanAssertion(types, 10, 8, false);
// list11 = list8;
delegateBooleanAssertion(types, 8, 11, false);
// list8 = list11;
delegateBooleanAssertion(types, 11, 8, false);
// list12 = list8;
delegateBooleanAssertion(types, 8, 12, false);
// list8 = list12;
delegateBooleanAssertion(types, 12, 8, false);
list13 = list8;
delegateBooleanAssertion(types, 8, 13, true);
list8 = (List<Object>[]) list13;
delegateBooleanAssertion(types, 13, 8, false);
// list9 = list9;
delegateBooleanAssertion(types, 9, 9, true);
list10 = (List<? super Object>[]) list9;
delegateBooleanAssertion(types, 9, 10, false);
list9 = list10;
delegateBooleanAssertion(types, 10, 9, true);
list11 = (List<String>[]) list9;
delegateBooleanAssertion(types, 9, 11, false);
list9 = list11;
delegateBooleanAssertion(types, 11, 9, true);
list12 = (List<? extends String>[]) list9;
delegateBooleanAssertion(types, 9, 12, false);
list9 = list12;
delegateBooleanAssertion(types, 12, 9, true);
list13 = (List<? super String>[]) list9;
delegateBooleanAssertion(types, 9, 13, false);
list9 = list13;
delegateBooleanAssertion(types, 13, 9, true);
// list10 = list10;
delegateBooleanAssertion(types, 10, 10, true);
// list11 = list10;
delegateBooleanAssertion(types, 10, 11, false);
// list10 = list11;
delegateBooleanAssertion(types, 11, 10, false);
// list12 = list10;
delegateBooleanAssertion(types, 10, 12, false);
// list10 = list12;
delegateBooleanAssertion(types, 12, 10, false);
list13 = list10;
delegateBooleanAssertion(types, 10, 13, true);
list10 = (List<? super Object>[]) list13;
delegateBooleanAssertion(types, 13, 10, false);
// list11 = list11;
delegateBooleanAssertion(types, 11, 11, true);
list12 = list11;
delegateBooleanAssertion(types, 11, 12, true);
list11 = (List<String>[]) list12;
delegateBooleanAssertion(types, 12, 11, false);
list13 = list11;
delegateBooleanAssertion(types, 11, 13, true);
list11 = (List<String>[]) list13;
delegateBooleanAssertion(types, 13, 11, false);
// list12 = list12;
delegateBooleanAssertion(types, 12, 12, true);
list13 = (List<? super String>[]) list12;
delegateBooleanAssertion(types, 12, 13, false);
list12 = (List<? extends String>[]) list13;
delegateBooleanAssertion(types, 13, 12, false);
// list13 = list13;
delegateBooleanAssertion(types, 13, 13, true);
final Type disType = getClass().getField("dis").getGenericType();
// Reporter.log( ( ( ParameterizedType ) disType
// ).getOwnerType().getClass().toString() );
final Type datType = getClass().getField("dat").getGenericType();
final Type daType = getClass().getField("da").getGenericType();
final Type uhderType = getClass().getField("uhder").getGenericType();
final Type dingType = getClass().getField("ding").getGenericType();
final Type testerType = getClass().getField("tester").getGenericType();
final Type tester2Type = getClass().getField("tester2").getGenericType();
final Type dat2Type = getClass().getField("dat2").getGenericType();
final Type dat3Type = getClass().getField("dat3").getGenericType();
dis = dat;
Assert.assertTrue(TypeUtils.isAssignable(datType, disType));
// dis = da;
Assert.assertFalse(TypeUtils.isAssignable(daType, disType));
dis = uhder;
Assert.assertTrue(TypeUtils.isAssignable(uhderType, disType));
dis = ding;
Assert.assertFalse(String.format("type %s not assignable to %s!", dingType, disType),
TypeUtils.isAssignable(dingType, disType));
dis = tester;
Assert.assertTrue(TypeUtils.isAssignable(testerType, disType));
// dis = tester2;
Assert.assertFalse(TypeUtils.isAssignable(tester2Type, disType));
// dat = dat2;
Assert.assertFalse(TypeUtils.isAssignable(dat2Type, datType));
// dat2 = dat;
Assert.assertFalse(TypeUtils.isAssignable(datType, dat2Type));
// dat = dat3;
Assert.assertFalse(TypeUtils.isAssignable(dat3Type, datType));
final char ch = 0;
final boolean bo = false;
final byte by = 0;
final short sh = 0;
int in = 0;
long lo = 0;
final float fl = 0;
double du = 0;
du = ch;
Assert.assertTrue(TypeUtils.isAssignable(char.class, double.class));
du = by;
Assert.assertTrue(TypeUtils.isAssignable(byte.class, double.class));
du = sh;
Assert.assertTrue(TypeUtils.isAssignable(short.class, double.class));
du = in;
Assert.assertTrue(TypeUtils.isAssignable(int.class, double.class));
du = lo;
Assert.assertTrue(TypeUtils.isAssignable(long.class, double.class));
du = fl;
Assert.assertTrue(TypeUtils.isAssignable(float.class, double.class));
lo = in;
Assert.assertTrue(TypeUtils.isAssignable(int.class, long.class));
lo = Integer.valueOf(0);
Assert.assertTrue(TypeUtils.isAssignable(Integer.class, long.class));
// Long lngW = 1;
Assert.assertFalse(TypeUtils.isAssignable(int.class, Long.class));
// lngW = Integer.valueOf( 0 );
Assert.assertFalse(TypeUtils.isAssignable(Integer.class, Long.class));
in = Integer.valueOf(0);
Assert.assertTrue(TypeUtils.isAssignable(Integer.class, int.class));
final Integer inte = in;
Assert.assertTrue(TypeUtils.isAssignable(int.class, Integer.class));
Assert.assertTrue(TypeUtils.isAssignable(int.class, Number.class));
Assert.assertTrue(TypeUtils.isAssignable(int.class, Object.class));
final Type intComparableType = getClass().getField("intComparable").getGenericType();
intComparable = 1;
Assert.assertTrue(TypeUtils.isAssignable(int.class, intComparableType));
Assert.assertTrue(TypeUtils.isAssignable(int.class, Comparable.class));
final Serializable ser = 1;
Assert.assertTrue(TypeUtils.isAssignable(int.class, Serializable.class));
final Type longComparableType = getClass().getField("longComparable").getGenericType();
// longComparable = 1;
Assert.assertFalse(TypeUtils.isAssignable(int.class, longComparableType));
// longComparable = Integer.valueOf( 0 );
Assert.assertFalse(TypeUtils.isAssignable(Integer.class, longComparableType));
// int[] ia;
// long[] la = ia;
Assert.assertFalse(TypeUtils.isAssignable(int[].class, long[].class));
final Integer[] ia = null;
final Type caType = getClass().getField("intWildcardComparable").getGenericType();
intWildcardComparable = ia;
Assert.assertTrue(TypeUtils.isAssignable(Integer[].class, caType));
// int[] ina = ia;
Assert.assertFalse(TypeUtils.isAssignable(Integer[].class, int[].class));
final int[] ina = null;
Object[] oa;
// oa = ina;
Assert.assertFalse(TypeUtils.isAssignable(int[].class, Object[].class));
oa = new Integer[0];
Assert.assertTrue(TypeUtils.isAssignable(Integer[].class, Object[].class));
final Type bClassType = AClass.class.getField("bClass").getGenericType();
final Type cClassType = AClass.class.getField("cClass").getGenericType();
final Type dClassType = AClass.class.getField("dClass").getGenericType();
final Type eClassType = AClass.class.getField("eClass").getGenericType();
final Type fClassType = AClass.class.getField("fClass").getGenericType();
final AClass aClass = new AClass(new AAClass<String>());
aClass.bClass = aClass.cClass;
Assert.assertTrue(TypeUtils.isAssignable(cClassType, bClassType));
aClass.bClass = aClass.dClass;
Assert.assertTrue(TypeUtils.isAssignable(dClassType, bClassType));
aClass.bClass = aClass.eClass;
Assert.assertTrue(TypeUtils.isAssignable(eClassType, bClassType));
aClass.bClass = aClass.fClass;
Assert.assertTrue(TypeUtils.isAssignable(fClassType, bClassType));
aClass.cClass = aClass.dClass;
Assert.assertTrue(TypeUtils.isAssignable(dClassType, cClassType));
aClass.cClass = aClass.eClass;
Assert.assertTrue(TypeUtils.isAssignable(eClassType, cClassType));
aClass.cClass = aClass.fClass;
Assert.assertTrue(TypeUtils.isAssignable(fClassType, cClassType));
aClass.dClass = aClass.eClass;
Assert.assertTrue(TypeUtils.isAssignable(eClassType, dClassType));
aClass.dClass = aClass.fClass;
Assert.assertTrue(TypeUtils.isAssignable(fClassType, dClassType));
aClass.eClass = aClass.fClass;
Assert.assertTrue(TypeUtils.isAssignable(fClassType, eClassType));
}
public void delegateBooleanAssertion(final Type[] types, final int i2, final int i1, final boolean expected) {
final Type type1 = types[i1];
final Type type2 = types[i2];
final boolean isAssignable = TypeUtils.isAssignable(type2, type1);
if (expected) {
Assert.assertTrue("[" + i1 + ", " + i2 + "]: From "
+ StringEscapeUtils.escapeHtml4(String.valueOf(type2)) + " to "
+ StringEscapeUtils.escapeHtml4(String.valueOf(type1)), isAssignable);
} else {
Assert.assertFalse("[" + i1 + ", " + i2 + "]: From "
+ StringEscapeUtils.escapeHtml4(String.valueOf(type2)) + " to "
+ StringEscapeUtils.escapeHtml4(String.valueOf(type1)), isAssignable);
}
}
@SuppressWarnings("boxing") // boxing is deliberate here
@Test
public void testIsInstance() throws SecurityException, NoSuchFieldException {
final Type intComparableType = getClass().getField("intComparable").getGenericType();
final Type uriComparableType = getClass().getField("uriComparable").getGenericType();
intComparable = 1;
Assert.assertTrue(TypeUtils.isInstance(1, intComparableType));
// uriComparable = 1;
Assert.assertFalse(TypeUtils.isInstance(1, uriComparableType));
}
@Test
public void testGetTypeArguments() {
Map<TypeVariable<?>, Type> typeVarAssigns;
TypeVariable<?> treeSetTypeVar;
Type typeArg;
typeVarAssigns = TypeUtils.getTypeArguments(Integer.class, Comparable.class);
treeSetTypeVar = Comparable.class.getTypeParameters()[0];
Assert.assertTrue("Type var assigns for Comparable from Integer: " + typeVarAssigns,
typeVarAssigns.containsKey(treeSetTypeVar));
typeArg = typeVarAssigns.get(treeSetTypeVar);
Assert.assertEquals("Type argument of Comparable from Integer: " + typeArg, Integer.class,
typeVarAssigns.get(treeSetTypeVar));
typeVarAssigns = TypeUtils.getTypeArguments(int.class, Comparable.class);
treeSetTypeVar = Comparable.class.getTypeParameters()[0];
Assert.assertTrue("Type var assigns for Comparable from int: " + typeVarAssigns,
typeVarAssigns.containsKey(treeSetTypeVar));
typeArg = typeVarAssigns.get(treeSetTypeVar);
Assert.assertEquals("Type argument of Comparable from int: " + typeArg, Integer.class,
typeVarAssigns.get(treeSetTypeVar));
final Collection<Integer> col = Arrays.asList(new Integer[0]);
typeVarAssigns = TypeUtils.getTypeArguments(List.class, Collection.class);
treeSetTypeVar = Comparable.class.getTypeParameters()[0];
Assert.assertFalse("Type var assigns for Collection from List: " + typeVarAssigns,
typeVarAssigns.containsKey(treeSetTypeVar));
typeVarAssigns = TypeUtils.getTypeArguments(AAAClass.BBBClass.class, AAClass.BBClass.class);
Assert.assertTrue(typeVarAssigns.size() == 2);
Assert.assertEquals(String.class, typeVarAssigns.get(AAClass.class.getTypeParameters()[0]));
Assert.assertEquals(String.class, typeVarAssigns.get(AAClass.BBClass.class.getTypeParameters()[0]));
typeVarAssigns = TypeUtils.getTypeArguments(Other.class, This.class);
Assert.assertEquals(2, typeVarAssigns.size());
Assert.assertEquals(String.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
Assert.assertEquals(Other.class.getTypeParameters()[0], typeVarAssigns.get(This.class.getTypeParameters()[1]));
typeVarAssigns = TypeUtils.getTypeArguments(And.class, This.class);
Assert.assertEquals(2, typeVarAssigns.size());
Assert.assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[0]));
Assert.assertEquals(Number.class, typeVarAssigns.get(This.class.getTypeParameters()[1]));
typeVarAssigns = TypeUtils.getTypeArguments(Thing.class, Other.class);
Assert.assertEquals(2, typeVarAssigns.size());
Assert.assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(getClass().getTypeParameters()[0]));
Assert.assertEquals(getClass().getTypeParameters()[0], typeVarAssigns.get(Other.class.getTypeParameters()[0]));
}
@Test
public void testTypesSatisfyVariables() throws SecurityException, NoSuchFieldException,
NoSuchMethodException {
final Map<TypeVariable<?>, Type> typeVarAssigns = new HashMap<TypeVariable<?>, Type>();
final Integer max = TypeUtilsTest.<Integer> stub();
typeVarAssigns.put(getClass().getMethod("stub").getTypeParameters()[0], Integer.class);
Assert.assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
typeVarAssigns.clear();
typeVarAssigns.put(getClass().getMethod("stub2").getTypeParameters()[0], Integer.class);
Assert.assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
typeVarAssigns.clear();
typeVarAssigns.put(getClass().getMethod("stub3").getTypeParameters()[0], Integer.class);
Assert.assertTrue(TypeUtils.typesSatisfyVariables(typeVarAssigns));
}
@Test
public void testDetermineTypeVariableAssignments() throws SecurityException,
NoSuchFieldException, NoSuchMethodException {
final ParameterizedType iterableType = (ParameterizedType) getClass().getField("iterable")
.getGenericType();
final Map<TypeVariable<?>, Type> typeVarAssigns = TypeUtils.determineTypeArguments(TreeSet.class,
iterableType);
final TypeVariable<?> treeSetTypeVar = TreeSet.class.getTypeParameters()[0];
Assert.assertTrue(typeVarAssigns.containsKey(treeSetTypeVar));
Assert.assertEquals(iterableType.getActualTypeArguments()[0], typeVarAssigns
.get(treeSetTypeVar));
}
@Test
public void testGetRawType() throws SecurityException, NoSuchFieldException {
final Type stringParentFieldType = GenericTypeHolder.class.getDeclaredField("stringParent")
.getGenericType();
final Type integerParentFieldType = GenericTypeHolder.class.getDeclaredField("integerParent")
.getGenericType();
final Type foosFieldType = GenericTypeHolder.class.getDeclaredField("foos").getGenericType();
final Type genericParentT = GenericParent.class.getTypeParameters()[0];
Assert.assertEquals(GenericParent.class, TypeUtils.getRawType(stringParentFieldType, null));
Assert
.assertEquals(GenericParent.class, TypeUtils.getRawType(integerParentFieldType,
null));
Assert.assertEquals(List.class, TypeUtils.getRawType(foosFieldType, null));
Assert.assertEquals(String.class, TypeUtils.getRawType(genericParentT,
StringParameterizedChild.class));
Assert.assertEquals(String.class, TypeUtils.getRawType(genericParentT,
stringParentFieldType));
Assert.assertEquals(Foo.class, TypeUtils.getRawType(Iterable.class.getTypeParameters()[0],
foosFieldType));
Assert.assertEquals(Foo.class, TypeUtils.getRawType(List.class.getTypeParameters()[0],
foosFieldType));
Assert.assertNull(TypeUtils.getRawType(genericParentT, GenericParent.class));
Assert.assertEquals(GenericParent[].class, TypeUtils.getRawType(GenericTypeHolder.class
.getDeclaredField("barParents").getGenericType(), null));
}
@Test
public void testIsArrayTypeClasses() {
Assert.assertTrue(TypeUtils.isArrayType(boolean[].class));
Assert.assertTrue(TypeUtils.isArrayType(byte[].class));
Assert.assertTrue(TypeUtils.isArrayType(short[].class));
Assert.assertTrue(TypeUtils.isArrayType(int[].class));
Assert.assertTrue(TypeUtils.isArrayType(char[].class));
Assert.assertTrue(TypeUtils.isArrayType(long[].class));
Assert.assertTrue(TypeUtils.isArrayType(float[].class));
Assert.assertTrue(TypeUtils.isArrayType(double[].class));
Assert.assertTrue(TypeUtils.isArrayType(Object[].class));
Assert.assertTrue(TypeUtils.isArrayType(String[].class));
Assert.assertFalse(TypeUtils.isArrayType(boolean.class));
Assert.assertFalse(TypeUtils.isArrayType(byte.class));
Assert.assertFalse(TypeUtils.isArrayType(short.class));
Assert.assertFalse(TypeUtils.isArrayType(int.class));
Assert.assertFalse(TypeUtils.isArrayType(char.class));
Assert.assertFalse(TypeUtils.isArrayType(long.class));
Assert.assertFalse(TypeUtils.isArrayType(float.class));
Assert.assertFalse(TypeUtils.isArrayType(double.class));
Assert.assertFalse(TypeUtils.isArrayType(Object.class));
Assert.assertFalse(TypeUtils.isArrayType(String.class));
}
@Test
public void testIsArrayGenericTypes() throws Exception {
final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
List.class, List.class, List.class, List.class, List[].class, List[].class,
List[].class, List[].class, List[].class, List[].class, List[].class);
final Type[] types = method.getGenericParameterTypes();
Assert.assertFalse(TypeUtils.isArrayType(types[0]));
Assert.assertFalse(TypeUtils.isArrayType(types[1]));
Assert.assertFalse(TypeUtils.isArrayType(types[2]));
Assert.assertFalse(TypeUtils.isArrayType(types[3]));
Assert.assertFalse(TypeUtils.isArrayType(types[4]));
Assert.assertFalse(TypeUtils.isArrayType(types[5]));
Assert.assertFalse(TypeUtils.isArrayType(types[6]));
Assert.assertTrue(TypeUtils.isArrayType(types[7]));
Assert.assertTrue(TypeUtils.isArrayType(types[8]));
Assert.assertTrue(TypeUtils.isArrayType(types[9]));
Assert.assertTrue(TypeUtils.isArrayType(types[10]));
Assert.assertTrue(TypeUtils.isArrayType(types[11]));
Assert.assertTrue(TypeUtils.isArrayType(types[12]));
Assert.assertTrue(TypeUtils.isArrayType(types[13]));
}
@Test
public void testGetPrimitiveArrayComponentType() throws Exception {
Assert.assertEquals(boolean.class, TypeUtils.getArrayComponentType(boolean[].class));
Assert.assertEquals(byte.class, TypeUtils.getArrayComponentType(byte[].class));
Assert.assertEquals(short.class, TypeUtils.getArrayComponentType(short[].class));
Assert.assertEquals(int.class, TypeUtils.getArrayComponentType(int[].class));
Assert.assertEquals(char.class, TypeUtils.getArrayComponentType(char[].class));
Assert.assertEquals(long.class, TypeUtils.getArrayComponentType(long[].class));
Assert.assertEquals(float.class, TypeUtils.getArrayComponentType(float[].class));
Assert.assertEquals(double.class, TypeUtils.getArrayComponentType(double[].class));
Assert.assertNull(TypeUtils.getArrayComponentType(boolean.class));
Assert.assertNull(TypeUtils.getArrayComponentType(byte.class));
Assert.assertNull(TypeUtils.getArrayComponentType(short.class));
Assert.assertNull(TypeUtils.getArrayComponentType(int.class));
Assert.assertNull(TypeUtils.getArrayComponentType(char.class));
Assert.assertNull(TypeUtils.getArrayComponentType(long.class));
Assert.assertNull(TypeUtils.getArrayComponentType(float.class));
Assert.assertNull(TypeUtils.getArrayComponentType(double.class));
}
@Test
public void testGetArrayComponentType() throws Exception {
final Method method = getClass().getMethod("dummyMethod", List.class, List.class, List.class,
List.class, List.class, List.class, List.class, List[].class, List[].class,
List[].class, List[].class, List[].class, List[].class, List[].class);
final Type[] types = method.getGenericParameterTypes();
Assert.assertNull(TypeUtils.getArrayComponentType(types[0]));
Assert.assertNull(TypeUtils.getArrayComponentType(types[1]));
Assert.assertNull(TypeUtils.getArrayComponentType(types[2]));
Assert.assertNull(TypeUtils.getArrayComponentType(types[3]));
Assert.assertNull(TypeUtils.getArrayComponentType(types[4]));
Assert.assertNull(TypeUtils.getArrayComponentType(types[5]));
Assert.assertNull(TypeUtils.getArrayComponentType(types[6]));
Assert.assertEquals(types[0], TypeUtils.getArrayComponentType(types[7]));
Assert.assertEquals(types[1], TypeUtils.getArrayComponentType(types[8]));
Assert.assertEquals(types[2], TypeUtils.getArrayComponentType(types[9]));
Assert.assertEquals(types[3], TypeUtils.getArrayComponentType(types[10]));
Assert.assertEquals(types[4], TypeUtils.getArrayComponentType(types[11]));
Assert.assertEquals(types[5], TypeUtils.getArrayComponentType(types[12]));
Assert.assertEquals(types[6], TypeUtils.getArrayComponentType(types[13]));
}
@Test
public void testLang820() throws Exception {
final Type[] typeArray = {String.class, String.class};
final Type[] expectedArray = {String.class};
Assert.assertArrayEquals(expectedArray, TypeUtils.normalizeUpperBounds(typeArray));
}
@Test
public void testParameterize() throws Exception {
final ParameterizedType stringComparableType = TypeUtils.parameterize(Comparable.class, String.class);
Assert.assertTrue(TypeUtils.equals(getClass().getField("stringComparable").getGenericType(),
stringComparableType));
Assert.assertEquals("java.lang.Comparable<java.lang.String>", stringComparableType.toString());
}
@Test
public void testParameterizeWithOwner() throws Exception {
final Type owner = TypeUtils.parameterize(TypeUtilsTest.class, String.class);
final ParameterizedType dat2Type = TypeUtils.parameterizeWithOwner(owner, That.class, String.class, String.class);
Assert.assertTrue(TypeUtils.equals(getClass().getField("dat2").getGenericType(), dat2Type));
}
@Test
public void testWildcardType() throws Exception {
final WildcardType simpleWildcard = TypeUtils.wildcardType().withUpperBounds(String.class).build();
final Field cClass = AClass.class.getField("cClass");
Assert.assertTrue(TypeUtils.equals(((ParameterizedType) cClass.getGenericType()).getActualTypeArguments()[0],
simpleWildcard));
Assert.assertEquals(String.format("? extends %s", String.class.getName()), TypeUtils.toString(simpleWildcard));
Assert.assertEquals(String.format("? extends %s", String.class.getName()), simpleWildcard.toString());
}
@Test
public void testUnboundedWildcardType() {
final WildcardType unbounded = TypeUtils.wildcardType().withLowerBounds((Type) null).withUpperBounds().build();
Assert.assertTrue(TypeUtils.equals(TypeUtils.WILDCARD_ALL, unbounded));
Assert.assertArrayEquals(new Type[] { Object.class }, TypeUtils.getImplicitUpperBounds(unbounded));
Assert.assertArrayEquals(new Type[] { null }, TypeUtils.getImplicitLowerBounds(unbounded));
Assert.assertEquals("?", TypeUtils.toString(unbounded));
Assert.assertEquals("?", unbounded.toString());
}
@Test
public void testLowerBoundedWildcardType() {
final WildcardType lowerBounded = TypeUtils.wildcardType().withLowerBounds(java.sql.Date.class).build();
Assert.assertEquals(String.format("? super %s", java.sql.Date.class.getName()), TypeUtils.toString(lowerBounded));
Assert.assertEquals(String.format("? super %s", java.sql.Date.class.getName()), lowerBounded.toString());
final TypeVariable<Class<Iterable>> iterableT0 = Iterable.class.getTypeParameters()[0];
final WildcardType lowerTypeVariable = TypeUtils.wildcardType().withLowerBounds(iterableT0).build();
Assert.assertEquals(String.format("? super %s", iterableT0.getName()), TypeUtils.toString(lowerTypeVariable));
Assert.assertEquals(String.format("? super %s", iterableT0.getName()), lowerTypeVariable.toString());
}
@Test
public void testLang1114() throws Exception {
final Type nonWildcardType = getClass().getDeclaredField("wildcardComparable").getGenericType();
final Type wildcardType = ((ParameterizedType)nonWildcardType).getActualTypeArguments()[0];
Assert.assertFalse(TypeUtils.equals(wildcardType, nonWildcardType));
Assert.assertFalse(TypeUtils.equals(nonWildcardType, wildcardType));
}
@Test
public void testGenericArrayType() throws Exception {
final Type expected = getClass().getField("intWildcardComparable").getGenericType();
final GenericArrayType actual =
TypeUtils.genericArrayType(TypeUtils.parameterize(Comparable.class, TypeUtils.wildcardType()
.withUpperBounds(Integer.class).build()));
Assert.assertTrue(TypeUtils.equals(expected, actual));
Assert.assertEquals("java.lang.Comparable<? extends java.lang.Integer>[]", actual.toString());
}
@Test
public void testToLongString() {
Assert.assertEquals(getClass().getName() + ":B", TypeUtils.toLongString(getClass().getTypeParameters()[0]));
}
@Test
public void testWrap() {
final Type t = getClass().getTypeParameters()[0];
Assert.assertTrue(TypeUtils.equals(t, TypeUtils.wrap(t).getType()));
Assert.assertEquals(String.class, TypeUtils.wrap(String.class).getType());
}
public static class ClassWithSuperClassWithGenericType extends ArrayList<Object> {
private static final long serialVersionUID = 1L;
public static <U> Iterable<U> methodWithGenericReturnType() {
return null;
}
}
@Test
public void testLANG1190() throws Exception {
Type fromType = ClassWithSuperClassWithGenericType.class.getDeclaredMethod("methodWithGenericReturnType").getGenericReturnType();
Type failingToType = TypeUtils.wildcardType().withLowerBounds(ClassWithSuperClassWithGenericType.class).build();
Assert.assertTrue(TypeUtils.isAssignable(fromType, failingToType));
}
public Iterable<? extends Map<Integer, ? extends Collection<?>>> iterable;
public static <G extends Comparable<G>> G stub() {
return null;
}
public static <G extends Comparable<? super G>> G stub2() {
return null;
}
public static <T extends Comparable<? extends T>> T stub3() {
return null;
}
}
class AAClass<T> {
public class BBClass<S> {
}
}
class AAAClass extends AAClass<String> {
public class BBBClass extends BBClass<String> {
}
}
@SuppressWarnings("rawtypes")
//raw types, where used, are used purposely
class AClass extends AAClass<String>.BBClass<Number> {
public AClass(final AAClass<String> enclosingInstance) {
enclosingInstance.super();
}
public class BClass<T> {
}
public class CClass<T> extends BClass {
}
public class DClass<T> extends CClass<T> {
}
public class EClass<T> extends DClass {
}
public class FClass extends EClass<String> {
}
public class GClass<T extends BClass<? extends T> & AInterface<AInterface<? super T>>> {
}
public BClass<Number> bClass;
public CClass<? extends String> cClass;
public DClass<String> dClass;
public EClass<String> eClass;
public FClass fClass;
public GClass gClass;
public interface AInterface<T> {
}
}