List of usage examples for org.apache.commons.lang3.reflect TypeUtils determineTypeArguments
public static Map<TypeVariable<?>, Type> determineTypeArguments(final Class<?> cls, final ParameterizedType superType)
Tries to determine the type arguments of a class/interface based on a super parameterized type's type arguments.
From source file:org.evosuite.utils.generic.GenericClass.java
/** * Determine if there exists an instantiation of the type variables such * that the class matches otherType/*from w w w. j a v a 2 s.c o m*/ * * @param otherType * is the class we want to generate * @return */ public boolean canBeInstantiatedTo(GenericClass otherType) { if (isPrimitive() && otherType.isWrapperType()) return false; if (isAssignableTo(otherType)) return true; if (!isTypeVariable() && !otherType.isTypeVariable() && otherType.isGenericSuperTypeOf(this)) return true; Class<?> otherRawClass = otherType.getRawClass(); if (otherRawClass.isAssignableFrom(rawClass)) { //logger.debug("Raw classes are assignable: " + otherType + ", have: " // + toString()); Map<TypeVariable<?>, Type> typeMap = otherType.getTypeVariableMap(); if (otherType.isParameterizedType()) { typeMap.putAll(TypeUtils.determineTypeArguments(rawClass, (ParameterizedType) otherType.getType())); } //logger.debug(typeMap.toString()); try { GenericClass instantiation = getGenericInstantiation(typeMap); if (equals(instantiation)) { //logger.debug("Instantiation is equal to original, so I think we can't assign: " // + instantiation); if (hasWildcardOrTypeVariables()) return false; else return true; } //logger.debug("Checking instantiation: " + instantiation); return instantiation.canBeInstantiatedTo(otherType); } catch (ConstructionFailedException e) { logger.debug("Failed to instantiate " + toString()); return false; } } // TODO logger.debug("Not assignable? Want: {}, have {}", otherType, toString()); return false; }
From source file:org.evosuite.utils.generic.GenericClass.java
/** * Instantiate type variable/*from w w w.j a v a 2 s . com*/ * * @param typeMap * @param recursionLevel * @return * @throws ConstructionFailedException */ private GenericClass getGenericTypeVariableInstantiation(Map<TypeVariable<?>, Type> typeMap, int recursionLevel) throws ConstructionFailedException { if (typeMap.containsKey(type)) { if (typeMap.get(type) == type) { throw new ConstructionFailedException("Type points to itself"); } logger.debug("Type contains " + toString() + ": " + typeMap); GenericClass selectedClass = new GenericClass(typeMap.get(type)).getGenericInstantiation(typeMap, recursionLevel + 1); if (!selectedClass.satisfiesBoundaries((TypeVariable<?>) type)) { logger.debug("Cannot be instantiated to: " + selectedClass); throw new ConstructionFailedException("Unable to instantiate " + toString()); } else { logger.debug("Can be instantiated to: " + selectedClass); } return selectedClass; } else { logger.debug("Type map does not contain " + toString() + ": " + typeMap); GenericClass selectedClass = CastClassManager.getInstance().selectCastClass((TypeVariable<?>) type, recursionLevel < Properties.MAX_GENERIC_DEPTH, typeMap); if (selectedClass == null) { throw new ConstructionFailedException("Unable to instantiate " + toString()); } logger.debug("Getting instantiation of type variable " + toString() + ": " + selectedClass); Map<TypeVariable<?>, Type> extendedMap = new HashMap<TypeVariable<?>, Type>(typeMap); extendedMap.putAll(getTypeVariableMap()); for (Type bound : ((TypeVariable<?>) type).getBounds()) { GenericClass boundClass = new GenericClass(bound); extendedMap.putAll(boundClass.getTypeVariableMap()); if (boundClass.isParameterizedType()) { Class<?> boundRawClass = boundClass.getRawClass(); if (boundRawClass.isAssignableFrom(selectedClass.getRawClass())) { Map<TypeVariable<?>, Type> xmap = TypeUtils.determineTypeArguments( selectedClass.getRawClass(), (ParameterizedType) boundClass.getType()); extendedMap.putAll(xmap); } } } logger.debug("Updated type variable map to " + extendedMap); GenericClass instantiation = selectedClass.getGenericInstantiation(extendedMap, recursionLevel + 1); typeMap.put((TypeVariable<?>) type, instantiation.getType()); return instantiation; } }
From source file:org.evosuite.utils.generic.GenericClass.java
/** * If this is a LinkedList<?> and the super class is a List<Integer> then * this returns a LinkedList<Integer> * /* w w w .j a v a 2 s . c o m*/ * @param superClass * @return * @throws ConstructionFailedException */ public GenericClass getWithParametersFromSuperclass(GenericClass superClass) throws ConstructionFailedException { GenericClass exactClass = new GenericClass(type); if (!(type instanceof ParameterizedType)) { exactClass.type = type; return exactClass; } ParameterizedType pType = (ParameterizedType) type; if (superClass.isParameterizedType()) { Map<TypeVariable<?>, Type> typeMap = TypeUtils.determineTypeArguments(rawClass, (ParameterizedType) superClass.getType()); return getGenericInstantiation(typeMap); } Class<?> targetClass = superClass.getRawClass(); Class<?> currentClass = rawClass; Type[] parameterTypes = new Type[superClass.getNumParameters()]; superClass.getParameterTypes().toArray(parameterTypes); if (targetClass.equals(currentClass)) { logger.info("Raw classes match, setting parameters to: " + superClass.getParameterTypes()); exactClass.type = new ParameterizedTypeImpl(currentClass, parameterTypes, pType.getOwnerType()); } else { Type ownerType = pType.getOwnerType(); Map<TypeVariable<?>, Type> superTypeMap = superClass.getTypeVariableMap(); Type[] origArguments = pType.getActualTypeArguments(); Type[] arguments = new Type[origArguments.length]; // For some reason, doing this would lead to arguments being // of component type TypeVariable, which would lead to // ArrayStoreException if we try to assign a WildcardType //Type[] arguments = Arrays.copyOf(origArguments, origArguments.length); for (int i = 0; i < origArguments.length; i++) arguments[i] = origArguments[i]; List<TypeVariable<?>> variables = getTypeVariables(); for (int i = 0; i < arguments.length; i++) { TypeVariable<?> var = variables.get(i); if (superTypeMap.containsKey(var)) { arguments[i] = superTypeMap.get(var); logger.info("Setting type variable " + var + " to " + superTypeMap.get(var)); } else if (arguments[i] instanceof WildcardType && i < parameterTypes.length) { logger.info("Replacing wildcard with " + parameterTypes[i]); logger.info("Lower Bounds: " + Arrays.asList(TypeUtils.getImplicitLowerBounds((WildcardType) arguments[i]))); logger.info("Upper Bounds: " + Arrays.asList(TypeUtils.getImplicitUpperBounds((WildcardType) arguments[i]))); logger.info("Type variable: " + variables.get(i)); if (!TypeUtils.isAssignable(parameterTypes[i], arguments[i])) { logger.info("Not assignable to bounds!"); return null; } else { boolean assignable = false; for (Type bound : variables.get(i).getBounds()) { if (TypeUtils.isAssignable(parameterTypes[i], bound)) { assignable = true; break; } } if (!assignable) { logger.info("Not assignable to type variable!"); return null; } } arguments[i] = parameterTypes[i]; } } GenericClass ownerClass = new GenericClass(ownerType).getWithParametersFromSuperclass(superClass); if (ownerClass == null) return null; exactClass.type = new ParameterizedTypeImpl(currentClass, arguments, ownerClass.getType()); } return exactClass; }
From source file:org.evosuite.utils.generic.GenericClass.java
/** * Determine whether the boundaries of the type variable are satisfied by * this class//from w ww. j a v a 2s. c o m * * @param typeVariable * @return */ public boolean satisfiesBoundaries(TypeVariable<?> typeVariable, Map<TypeVariable<?>, Type> typeMap) { boolean isAssignable = true; // logger.debug("Checking class: " + type + " against type variable " + typeVariable+" with map "+typeMap); Map<TypeVariable<?>, Type> ownerVariableMap = getTypeVariableMap(); for (Type bound : typeVariable.getBounds()) { if (bound instanceof ParameterizedType) { Class<?> boundClass = GenericTypeReflector.erase(bound); if (boundClass.isAssignableFrom(rawClass)) { Map<TypeVariable<?>, Type> xmap = TypeUtils.determineTypeArguments(rawClass, (ParameterizedType) bound); ownerVariableMap.putAll(xmap); } } } ownerVariableMap.putAll(typeMap); boolean changed = true; while (changed) { changed = false; for (TypeVariable<?> var : ownerVariableMap.keySet()) { //logger.debug("Type var: "+var+" of "+var.getGenericDeclaration()); if (ownerVariableMap.get(var) instanceof TypeVariable<?>) { //logger.debug("Is set to type var: "+ownerVariableMap.get(var)+" of "+((TypeVariable<?>)ownerVariableMap.get(var)).getGenericDeclaration()); TypeVariable<?> value = (TypeVariable<?>) ownerVariableMap.get(var); if (ownerVariableMap.containsKey(value)) { Type other = ownerVariableMap.get(value); if (var != other && value != other) { //logger.debug("Replacing "+var+" with "+other); ownerVariableMap.put(var, other); changed = true; } } else { //logger.debug("Not in map: "+value); } } else { //logger.debug("Is set to concrete type: "+ownerVariableMap.get(var)); } } //logger.debug("Current iteration of map: " + ownerVariableMap); } GenericClass concreteClass = new GenericClass(GenericUtils.replaceTypeVariables(type, ownerVariableMap)); //logger.debug("Concrete class after variable replacement: " + concreteClass); for (Type theType : typeVariable.getBounds()) { //logger.debug("Current boundary of " + typeVariable + ": " + theType); // Special case: Enum is defined as Enum<T extends Enum> if (GenericTypeReflector.erase(theType).equals(Enum.class)) { //logger.debug("Is ENUM case"); // if this is an enum then it's ok. if (isEnum()) { //logger.debug("Class " + toString() + " is an enum!"); continue; } else { // If it's not an enum, it cannot be assignable to enum! //logger.debug("Class " + toString() + " is not an enum."); isAssignable = false; break; } } Type boundType = GenericUtils.replaceTypeVariables(theType, ownerVariableMap); boundType = GenericUtils.replaceTypeVariable(boundType, typeVariable, getType()); boundType = GenericUtils.replaceTypeVariablesWithWildcards(boundType); //logger.debug("Bound after variable replacement: " + boundType); if (!concreteClass.isAssignableTo(boundType) && !(boundType instanceof WildcardType)) { //logger.debug("Not assignable: " + type + " and " + boundType); // If the boundary is not assignable it may still be possible // to instantiate the generic to an assignable type if (GenericTypeReflector.erase(boundType).isAssignableFrom(getRawClass())) { //logger.debug("Raw classes are assignable: " + boundType + ", " // + getRawClass()); Type instanceType = GenericTypeReflector.getExactSuperType(boundType, getRawClass()); if (instanceType == null) { // This happens when the raw class is not a supertype // of the boundary //logger.debug("Instance type is null"); isAssignable = false; break; } // GenericClass instanceClass = new GenericClass(instanceType, // getRawClass()); // logger.debug("Instance type is " + instanceType); // if (instanceClass.hasTypeVariables()) // logger.debug("Instance type has type variables"); // if (instanceClass.hasWildcardTypes()) // logger.debug("Instance type has wildcard variables"); boundType = GenericUtils.replaceTypeVariable(theType, typeVariable, instanceType); // logger.debug("Instance type after replacement is " + boundType); if (GenericClass.isAssignable(boundType, instanceType)) { //logger.debug("Found assignable generic exact type: " // + instanceType); continue; } else { //logger.debug("Is not assignable: " + boundType + " and " // + instanceType); } } isAssignable = false; break; } } //logger.debug("Result: is assignable " + isAssignable); return isAssignable; }
From source file:org.evosuite.utils.generic.GenericUtils.java
/** * TODO: Try to match p2 superclasses? /*w ww. j a va 2s . co m*/ * * @param p1 Desired TypeVariable assignment * @param p2 Generic type with the TypeVariables that need assignment * @return */ public static Map<TypeVariable<?>, Type> getMatchingTypeParameters(ParameterizedType p1, ParameterizedType p2) { logger.debug("Matching generic types between " + p1 + " and " + p2); Map<TypeVariable<?>, Type> map = new HashMap<TypeVariable<?>, Type>(); if (!p1.getRawType().equals(p2.getRawType())) { logger.debug("Raw types do not match!"); GenericClass ownerClass = new GenericClass(p2); if (GenericClass.isSubclass(p1.getRawType(), p2.getRawType())) { logger.debug(p1 + " is a super type of " + p2); Map<TypeVariable<?>, Type> commonsMap = TypeUtils.determineTypeArguments((Class<?>) p2.getRawType(), p1); logger.debug("Adding to map: " + commonsMap); // TODO: Now we would need to iterate over the type parameters, and update the map? //map.putAll(commonsMap); for (TypeVariable<?> t : map.keySet()) { logger.debug(t + ": " + t.getGenericDeclaration()); } // For each type variable of the raw type, map the parameter type to that type Type[] p2TypesA = ((Class<?>) p2.getRawType()).getTypeParameters(); Type[] p2TypesB = p2.getActualTypeArguments(); for (int i = 0; i < p2TypesA.length; i++) { Type a = p2TypesA[i]; Type b = p2TypesB[i]; logger.debug("Should be mapping " + a + " and " + b); if (a instanceof TypeVariable<?>) { logger.debug(a + " is a type variable: " + ((TypeVariable<?>) a).getGenericDeclaration()); if (b instanceof TypeVariable<?>) { logger.debug( b + " is a type variable: " + ((TypeVariable<?>) b).getGenericDeclaration()); if (commonsMap.containsKey((TypeVariable<?>) a) && !(commonsMap.get((TypeVariable<?>) a) instanceof WildcardType) && !(commonsMap.get((TypeVariable<?>) a) instanceof TypeVariable<?>)) map.put((TypeVariable<?>) b, commonsMap.get((TypeVariable<?>) a)); //else // map.put((TypeVariable<?>)a, b); } } // if(b instanceof TypeVariable<?>) { // if(map.containsKey(a)) // map.put((TypeVariable<?>)b, map.get(a)); // //else // // map.put((TypeVariable<?>)b, a); // } logger.debug("Updated map: " + map); } } for (GenericClass interfaceClass : ownerClass.getInterfaces()) { if (interfaceClass.isParameterizedType()) map.putAll(getMatchingTypeParameters(p1, (ParameterizedType) interfaceClass.getType())); else logger.debug("Interface " + interfaceClass + " is not parameterized"); } if (ownerClass.getRawClass().getSuperclass() != null) { GenericClass ownerSuperClass = ownerClass.getSuperClass(); if (ownerSuperClass.isParameterizedType()) map.putAll(getMatchingTypeParameters(p1, (ParameterizedType) ownerSuperClass.getType())); else logger.debug("Super type " + ownerSuperClass + " is not parameterized"); } return map; } for (int i = 0; i < p1.getActualTypeArguments().length; i++) { Type t1 = p1.getActualTypeArguments()[i]; Type t2 = p2.getActualTypeArguments()[i]; if (t1 == t2) continue; logger.debug("First match: " + t1 + " - " + t2); if (t1 instanceof TypeVariable<?>) { map.put((TypeVariable<?>) t1, t2); } if (t2 instanceof TypeVariable<?>) { map.put((TypeVariable<?>) t2, t1); } else if (t2 instanceof ParameterizedType && t1 instanceof ParameterizedType) { map.putAll(getMatchingTypeParameters((ParameterizedType) t1, (ParameterizedType) t2)); } logger.debug("Updated map: " + map); } if (p1.getOwnerType() != null && p1.getOwnerType() instanceof ParameterizedType && p2.getOwnerType() instanceof ParameterizedType) { map.putAll(getMatchingTypeParameters((ParameterizedType) p1.getOwnerType(), (ParameterizedType) p2.getOwnerType())); } return map; }
From source file:org.evosuite.utils.GenericClass.java
/** * Determine if there exists an instantiation of the type variables such * that the class matches otherType/*w w w .ja v a 2 s . c o m*/ * * @param otherType * is the class we want to generate * @return */ public boolean canBeInstantiatedTo(GenericClass otherType) { if (isPrimitive() && otherType.isWrapperType()) return false; if (isAssignableTo(otherType)) return true; if (!isTypeVariable() && !otherType.isTypeVariable() && otherType.isGenericSuperTypeOf(this)) return true; Class<?> otherRawClass = otherType.getRawClass(); if (otherRawClass.isAssignableFrom(rawClass)) { logger.debug("Raw classes are assignable: {}, have: {}", otherType, toString()); Map<TypeVariable<?>, Type> typeMap = otherType.getTypeVariableMap(); if (otherType.isParameterizedType()) { typeMap.putAll(TypeUtils.determineTypeArguments(rawClass, (ParameterizedType) otherType.getType())); } logger.debug(typeMap.toString()); try { GenericClass instantiation = getGenericInstantiation(typeMap); if (equals(instantiation)) { logger.debug("Instantiation is equal to original, so I think we can't assign: {}", instantiation); if (hasWildcardOrTypeVariables()) return false; else return true; } logger.debug("Checking instantiation: {}", instantiation); return instantiation.canBeInstantiatedTo(otherType); } catch (ConstructionFailedException e) { logger.debug("Failed to instantiate {}", toString()); return false; } } // TODO logger.debug("Not assignable? Want: {}, have: {}", otherType, toString()); return false; }
From source file:org.evosuite.utils.GenericClass.java
/** * Instantiate type variable//from ww w .j ava 2s.c om * * @param typeMap * @param recursionLevel * @return * @throws ConstructionFailedException */ private GenericClass getGenericTypeVariableInstantiation(Map<TypeVariable<?>, Type> typeMap, int recursionLevel) throws ConstructionFailedException { if (typeMap.containsKey(type)) { if (typeMap.get(type) == type) { throw new ConstructionFailedException("Type points to itself"); } logger.debug("Type contains {}: {}", toString(), typeMap); GenericClass selectedClass = new GenericClass(typeMap.get(type)).getGenericInstantiation(typeMap, recursionLevel + 1); if (!selectedClass.satisfiesBoundaries((TypeVariable<?>) type)) { logger.debug("Cannot be instantiated to: {}", selectedClass); throw new ConstructionFailedException("Unable to instantiate " + toString()); } else { logger.debug("Can be instantiated to: {}", selectedClass); } return selectedClass; } else { logger.debug("Type map does not contain {}: {}", toString(), typeMap); GenericClass selectedClass = CastClassManager.getInstance().selectCastClass((TypeVariable<?>) type, recursionLevel < Properties.MAX_GENERIC_DEPTH, typeMap); if (selectedClass == null) { throw new ConstructionFailedException("Unable to instantiate " + toString()); } logger.debug("Getting instantiation of type variable {}: {}", toString(), selectedClass); Map<TypeVariable<?>, Type> extendedMap = new HashMap<TypeVariable<?>, Type>(typeMap); extendedMap.putAll(getTypeVariableMap()); for (Type bound : ((TypeVariable<?>) type).getBounds()) { GenericClass boundClass = new GenericClass(bound); extendedMap.putAll(boundClass.getTypeVariableMap()); if (boundClass.isParameterizedType()) { Class<?> boundRawClass = boundClass.getRawClass(); if (boundRawClass.isAssignableFrom(selectedClass.getRawClass())) { Map<TypeVariable<?>, Type> xmap = TypeUtils.determineTypeArguments( selectedClass.getRawClass(), (ParameterizedType) boundClass.getType()); extendedMap.putAll(xmap); } } } logger.debug("Updated type variable map to {}", extendedMap); GenericClass instantiation = selectedClass.getGenericInstantiation(extendedMap, recursionLevel + 1); typeMap.put((TypeVariable<?>) type, instantiation.getType()); return instantiation; } }
From source file:org.evosuite.utils.GenericClass.java
/** * If this is a LinkedList<?> and the super class is a List<Integer> then * this returns a LinkedList<Integer> * /*from w w w . j a va 2s .co m*/ * @param superClass * @return * @throws ConstructionFailedException */ public GenericClass getWithParametersFromSuperclass(GenericClass superClass) throws ConstructionFailedException { GenericClass exactClass = new GenericClass(type); if (!(type instanceof ParameterizedType)) { exactClass.type = type; return exactClass; } ParameterizedType pType = (ParameterizedType) type; if (superClass.isParameterizedType()) { Map<TypeVariable<?>, Type> typeMap = TypeUtils.determineTypeArguments(rawClass, (ParameterizedType) superClass.getType()); return getGenericInstantiation(typeMap); } Class<?> targetClass = superClass.getRawClass(); Class<?> currentClass = rawClass; Type[] parameterTypes = new Type[superClass.getNumParameters()]; superClass.getParameterTypes().toArray(parameterTypes); if (targetClass.equals(currentClass)) { logger.info("Raw classes match, setting parameters to: {}", superClass.getParameterTypes()); exactClass.type = new ParameterizedTypeImpl(currentClass, parameterTypes, pType.getOwnerType()); } else { Type ownerType = pType.getOwnerType(); Map<TypeVariable<?>, Type> superTypeMap = superClass.getTypeVariableMap(); Type[] origArguments = pType.getActualTypeArguments(); Type[] arguments = Arrays.copyOf(origArguments, origArguments.length); List<TypeVariable<?>> variables = getTypeVariables(); for (int i = 0; i < arguments.length; i++) { TypeVariable<?> var = variables.get(i); if (superTypeMap.containsKey(var)) { arguments[i] = superTypeMap.get(var); logger.info("Setting type variable {} to {}", var, superTypeMap.get(var)); } else if (arguments[i] instanceof WildcardType && i < parameterTypes.length) { logger.info("Replacing wildcard with {}", parameterTypes[i]); logger.info("Lower Bounds: {}", Arrays.asList(TypeUtils.getImplicitLowerBounds((WildcardType) arguments[i]))); logger.info("Upper Bounds: {}", Arrays.asList(TypeUtils.getImplicitUpperBounds((WildcardType) arguments[i]))); logger.info("Type variable: {}", variables.get(i)); if (!TypeUtils.isAssignable(parameterTypes[i], arguments[i])) { logger.info("Not assignable to bounds!"); return null; } else { boolean assignable = false; for (Type bound : variables.get(i).getBounds()) { if (TypeUtils.isAssignable(parameterTypes[i], bound)) { assignable = true; break; } } if (!assignable) { logger.info("Not assignable to type variable!"); return null; } } arguments[i] = parameterTypes[i]; } } GenericClass ownerClass = new GenericClass(ownerType).getWithParametersFromSuperclass(superClass); if (ownerClass == null) return null; exactClass.type = new ParameterizedTypeImpl(currentClass, arguments, ownerClass.getType()); } return exactClass; }
From source file:org.evosuite.utils.GenericClass.java
/** * Determine whether the boundaries of the type variable are satisfied by * this class// w ww .j av a 2s .co m * * @param typeVariable * @return */ public boolean satisfiesBoundaries(TypeVariable<?> typeVariable, Map<TypeVariable<?>, Type> typeMap) { boolean isAssignable = true; logger.debug("Checking class: {} against type variable {} with map {}", type, typeVariable, typeMap); Map<TypeVariable<?>, Type> ownerVariableMap = getTypeVariableMap(); for (Type bound : typeVariable.getBounds()) { if (bound instanceof ParameterizedType) { Class<?> boundClass = GenericTypeReflector.erase(bound); if (boundClass.isAssignableFrom(rawClass)) { Map<TypeVariable<?>, Type> xmap = TypeUtils.determineTypeArguments(rawClass, (ParameterizedType) bound); ownerVariableMap.putAll(xmap); } } } ownerVariableMap.putAll(typeMap); boolean changed = true; while (changed) { changed = false; for (TypeVariable<?> var : ownerVariableMap.keySet()) { logger.debug("Type var: {} of {}", var, var.getGenericDeclaration()); if (ownerVariableMap.get(var) instanceof TypeVariable<?>) { logger.debug("Is set to type var: {} of {}", ownerVariableMap.get(var), ((TypeVariable<?>) ownerVariableMap.get(var)).getGenericDeclaration()); TypeVariable<?> value = (TypeVariable<?>) ownerVariableMap.get(var); if (ownerVariableMap.containsKey(value)) { logger.debug("Replacing {} with {}", var, ownerVariableMap.get(value)); ownerVariableMap.put(var, ownerVariableMap.get(value)); changed = true; } else { logger.debug("Not in map: {}", value); } } else { logger.debug("Is set to concrete type: {}", ownerVariableMap.get(var)); } } logger.debug("Current iteration of map: {}", ownerVariableMap); } GenericClass concreteClass = new GenericClass(GenericUtils.replaceTypeVariables(type, ownerVariableMap)); logger.debug("Concrete class after variable replacement: {}", concreteClass); for (Type theType : typeVariable.getBounds()) { logger.debug("Current boundary of {}: {}", typeVariable, theType); // Special case: Enum is defined as Enum<T extends Enum> if (GenericTypeReflector.erase(theType).equals(Enum.class)) { logger.debug("Is ENUM case"); // if this is an enum then it's ok. if (isEnum()) { logger.debug("Class {} is an enum!", toString()); continue; } else { // If it's not an enum, it cannot be assignable to enum! logger.debug("Class {} is not an enum.", toString()); isAssignable = false; break; } } Type boundType = GenericUtils.replaceTypeVariables(theType, ownerVariableMap); boundType = GenericUtils.replaceTypeVariable(boundType, typeVariable, getType()); boundType = GenericUtils.replaceTypeVariablesWithWildcards(boundType); logger.debug("Bound after variable replacement: {}", boundType); if (!concreteClass.isAssignableTo(boundType)) { logger.debug("Not assignable: {} and {}", type, boundType); // If the boundary is not assignable it may still be possible // to instantiate the generic to an assignable type if (GenericTypeReflector.erase(boundType).isAssignableFrom(getRawClass())) { logger.debug("Raw classes are assignable: {}, {}", boundType, getRawClass()); Type instanceType = GenericTypeReflector.getExactSuperType(boundType, getRawClass()); if (instanceType == null) { // This happens when the raw class is not a supertype // of the boundary logger.debug("Instance type is null"); isAssignable = false; break; } GenericClass instanceClass = new GenericClass(instanceType, getRawClass()); logger.debug("Instance type is {}", instanceType); if (instanceClass.hasTypeVariables()) logger.debug("Instance type has type variables"); if (instanceClass.hasWildcardTypes()) logger.debug("Instance type has wildcard variables"); boundType = GenericUtils.replaceTypeVariable(theType, typeVariable, instanceType); logger.debug("Instance type after replacement is {}", boundType); if (GenericClass.isAssignable(boundType, instanceType)) { logger.debug("Found assignable generic exact type: {}", instanceType); continue; } else { logger.debug("Is not assignable: {} and {}", boundType, instanceType); } } isAssignable = false; break; } } logger.debug("Result: is assignable {}", isAssignable); return isAssignable; }
From source file:therian.operator.convert.AssignableElementConverter.java
protected Type targetComponentType(Typed<?> item) { final Type t = item.getType(); final Class<?> varOwner = targetElementType.getGenericDeclaration(); if (t instanceof Class<?>) { // raw//from w w w. j a v a 2 s . c o m return Object.class; } if (TypeUtils.isAssignable(t, varOwner)) { return TypeUtils.unrollVariables(TypeUtils.getTypeArguments(t, varOwner), targetElementType); } if (t instanceof ParameterizedType) { final Map<TypeVariable<?>, Type> args = TypeUtils.determineTypeArguments(varOwner, (ParameterizedType) t); return args.get(targetElementType); } return null; }