private Object convert( Type targetType, Object sourceObject, Action<? super SourceObjectMapping> mapping) { if (targetType instanceof ParameterizedType) { ParameterizedType parameterizedTargetType = (ParameterizedType) targetType; if (parameterizedTargetType.getRawType() instanceof Class) { Class<?> rawClass = (Class<?>) parameterizedTargetType.getRawType(); if (Iterable.class.isAssignableFrom(rawClass)) { Type targetElementType = getElementType(parameterizedTargetType, 0); return convertCollectionInternal( rawClass, targetElementType, (Iterable<?>) sourceObject, mapping); } if (Map.class.isAssignableFrom(rawClass)) { Type targetKeyType = getElementType(parameterizedTargetType, 0); Type targetValueType = getElementType(parameterizedTargetType, 1); return convertMap( rawClass, targetKeyType, targetValueType, (Map<?, ?>) sourceObject, mapping); } } } if (targetType instanceof Class) { if (((Class) targetType).isPrimitive()) { return sourceObject; } return adapt((Class) targetType, sourceObject, mapping); } throw new UnsupportedOperationException( String.format("Cannot convert object of %s to %s.", sourceObject.getClass(), targetType)); }
private boolean argsEquivalent(ParameterizedType ancestor) { for (int i = 0; i < ancestor.typeArguments().size(); i++) { Type arg1 = (Type) ancestor.typeArguments().get(i); Type arg2 = (Type) typeArguments().get(i); IntersectionType cap1 = (IntersectionType) ancestor.typeVariables().get(i); IntersectionType cap2 = (IntersectionType) baseType().typeVariables().get(i); // if both are AnySubType then arg2 bound must be subtype // of arg1 bound if (arg1 instanceof AnySubType) { if (arg2 instanceof AnySubType) { if (!typeSystem().equals(((AnySubType) arg2).bound(), ((AnySubType) arg1).bound())) return false; } else if (arg2 instanceof AnySuperType) { if (!typeSystem().equals(((AnySubType) arg1).bound(), ((AnySuperType) arg2).bound())) return false; } else if (arg2 instanceof IntersectionType) { // need to break out here or will recurse for ever if (((IntersectionType) arg2) .name() .equals(((IntersectionType) ((AnySubType) arg1).bound()).name())) return true; } // if only ancestor(arg1) is AnySubType then arg2 is not // wildcard must be subtype of bound of arg1 else { if (!typeSystem().equals(arg2, arg1)) return false; } } // if both are AnySuperType then arg1 bound must be a subtype // of arg2 bound else if (arg1 instanceof AnySuperType) { if (arg2 instanceof AnySuperType) { if (!typeSystem().equals(((AnySuperType) arg1).bound(), ((AnySuperType) arg2).bound())) return false; } // if only arg1 instanceof AnySuperType then arg1 bounds // must be a subtype of arg2 else { if (!typeSystem().equals(arg1, arg2)) return false; } } else if (arg1 instanceof AnyType) { if (arg2 instanceof AnyType) { if (!typeSystem().equals(((AnyType) arg1).upperBound(), ((AnyType) arg2).upperBound())) return false; } else { if (!typeSystem().equals(arg1, arg2)) return false; } } else if (arg1 instanceof ParameterizedType && arg2 instanceof ParameterizedType) { // if (arg1.equals(arg2)) return true; if (!typeSystem().equals(arg1, arg2)) return false; } else if (arg1 instanceof IntersectionType && arg2 instanceof IntersectionType) { if (!typeSystem().equals(arg1, arg2) && !((JL5TypeSystem) typeSystem()).isEquivalent(arg1, arg2)) return false; } else { if (!typeSystem().equals(arg1, arg2)) return false; } } return true; }
/** * Returns the generic type information of an attribute. * * @param field the field representation of the attribute. * @return an array of types that are used to parameterize the attribute. */ public static Class<?>[] getGenericTypes(Field field) { Type genericFieldType = field.getGenericType(); if (!(genericFieldType instanceof ParameterizedType)) return null; // type is not generic ParameterizedType pType = (ParameterizedType) genericFieldType; Type[] args = pType.getActualTypeArguments(); Class<?>[] types = new Class[args.length]; System.arraycopy(args, 0, types, 0, args.length); return types; }
private Object replace(Class<?> type, ApplicableGenerator generator, boolean alternative) { for (Creator<?> creator : creators) { ParameterizedType generic = (ParameterizedType) creator.getClass().getGenericInterfaces()[0]; Class<?> restrained = generic.getActualTypeArguments()[0] instanceof ParameterizedType ? (Class<?>) ((ParameterizedType) generic.getActualTypeArguments()[0]).getRawType() : (Class<?>) generic.getActualTypeArguments()[0]; if (type.isAssignableFrom(restrained)) { return creator.create(); } } return generator.generate(type, alternative); }
@SuppressWarnings("unchecked") private void apply(Object mock) { for (Refinement refinement : refinements) { ParameterizedType generic = (ParameterizedType) refinement.getClass().getGenericInterfaces()[0]; Class<?> restrained = generic.getActualTypeArguments()[0] instanceof ParameterizedType ? (Class<?>) ((ParameterizedType) generic.getActualTypeArguments()[0]).getRawType() : (Class<?>) generic.getActualTypeArguments()[0]; if (restrained.isInstance(mock)) { refinement.apply(mock); } } }
private Object generate(Class<?> type, boolean alternative) { for (Generator<?> generator : generators) { ParameterizedType generic = (ParameterizedType) generator.getClass().getGenericInterfaces()[0]; Class<?> restrained = generic.getActualTypeArguments()[0] instanceof ParameterizedType ? (Class<?>) ((ParameterizedType) generic.getActualTypeArguments()[0]).getRawType() : (Class<?>) generic.getActualTypeArguments()[0]; if (type.isAssignableFrom(restrained)) { type = generator.generate(); } } return type == String.class ? alternative ? OTHER_STRING : DEFAULT_STRING : mock(type); }
private Class<?> resolveReturnType(Method me) { Type returnType = me.getGenericReturnType(); if (returnType instanceof ParameterizedType) { ParameterizedType type = (ParameterizedType) returnType; Type[] typeArguments = type.getActualTypeArguments(); for (Type typeArgument : typeArguments) { if (typeArgument instanceof Class<?>) { return (Class<?>) typeArgument; } } return null; } return (Class<?>) returnType; }
public static <C, I> Type[] getGenericInterfaceParams( Class<C> checkedClass, Class<I> searchedInterface) { for (Type type : checkedClass.getGenericInterfaces()) { ParameterizedType pt = (ParameterizedType) type; if (searchedInterface.equals(pt.getRawType())) { ParameterizedType pType = ((ParameterizedType) type); return pType.getActualTypeArguments(); } } if (!Object.class.equals(checkedClass.getSuperclass())) return getGenericInterfaceParams(checkedClass.getSuperclass(), searchedInterface); throw new ConfigurationError( checkedClass + " does not implement interface with generic parameters: " + searchedInterface); }
private Type getElementType(ParameterizedType type, int index) { Type elementType = type.getActualTypeArguments()[index]; if (elementType instanceof WildcardType) { WildcardType wildcardType = (WildcardType) elementType; return wildcardType.getUpperBounds()[0]; } return elementType; }
public Type convertToInferred(List typeVars, List inferredTypes) { List newBounds = new ArrayList(); for (Iterator it = typeArguments().iterator(); it.hasNext(); ) { Type next = (Type) it.next(); if (next instanceof IntersectionType) { newBounds.add(inferredTypes.get(typeVars.indexOf(next))); } else if (next instanceof ParameterizedType) { newBounds.add(((ParameterizedType) next).convertToInferred(typeVars, inferredTypes)); } /*else if (next instanceof AnySubType){ newBounds.add(((AnySubType)next).convertToInferred(typeVars, inferredTypes)); }*/ else { newBounds.add(next); } } ParameterizedType converted = ((JL5TypeSystem) typeSystem()).parameterizedType(this.baseType()); converted.typeArguments(newBounds); return converted; }
protected static GenericsInfo ParseGenerics(ParameterizedType parameterized) { GenericsInfo generics = null; if (parameterized != null && parameterized.typeArguments() != null && parameterized.typeArguments().length > 0) { generics = new GenericsInfo(); Type[] types = parameterized.typeArguments(); TypeInfo[] typeInfoList = new TypeInfo[types.length]; for (int i = 0; i < types.length; i++) { typeInfoList[i] = ParseType(types[i]); } generics.typeArguments = typeInfoList; } return generics; }
private static void findAllInterfaceTypes( Map results, ParameterizedType p, Configuration configuration) { Type superType = p.superclassType(); if (superType == null) return; addAllInterfaceTypes( results, superType, superType instanceof ClassDoc ? ((ClassDoc) superType).interfaceTypes() : ((ParameterizedType) superType).interfaceTypes(), false, configuration); }
protected void registerTypeVariablesOn(Type classType) { if (!(classType instanceof ParameterizedType)) { return; } ParameterizedType parameterizedType = (ParameterizedType) classType; TypeVariable[] typeParameters = ((Class<?>) parameterizedType.getRawType()).getTypeParameters(); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); for (int i = 0; i < actualTypeArguments.length; i++) { TypeVariable typeParameter = typeParameters[i]; Type actualTypeArgument = actualTypeArguments[i]; if (actualTypeArgument instanceof WildcardType) { contextualActualTypeParameters.put( typeParameter, boundsOf((WildcardType) actualTypeArgument)); } else { contextualActualTypeParameters.put(typeParameter, actualTypeArgument); } // logger.log("For '" + parameterizedType + "' found type variable : { '" + typeParameter + // "(" + System.identityHashCode(typeParameter) + ")" + "' : '" + actualTypeArgument + "(" + // System.identityHashCode(typeParameter) + ")" + "' }"); } }
/** * Gets the actual type arguments that are used in a given implementation of a given generic base * class or interface. (Based on code copyright 2007 by Ian Robertson). * * @param base the generic base class or interface * @param implementation the type (potentially) implementing the given base class or interface * @return a list of the raw classes for the actual type arguments. */ @NotNull public static List<Class<?>> getTypeArguments( @NotNull Class<?> base, @NotNull Class<?> implementation) { Map<Type, Type> resolvedTypes = new HashMap<Type, Type>(); // first we need to resolve all supertypes up to the required base class or interface // and find the right Type for it Type type; Queue<Type> toCheck = new LinkedList<Type>(); toCheck.add(implementation); while (true) { // if we have checked everything and not found the base class we return an empty list if (toCheck.isEmpty()) return ImmutableList.of(); type = toCheck.remove(); Class<?> clazz; if (type instanceof Class) { // there is no useful information for us in raw types, so just keep going up the inheritance // chain clazz = (Class) type; if (base.isInterface()) { // if we are actually looking for the type parameters to an interface we also need to // look at all the ones implemented by the given current one toCheck.addAll(Arrays.asList(clazz.getGenericInterfaces())); } } else if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; clazz = (Class) parameterizedType.getRawType(); // for instances of ParameterizedType we extract and remember all type arguments TypeVariable<?>[] typeParameters = clazz.getTypeParameters(); Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); for (int i = 0; i < actualTypeArguments.length; i++) { resolvedTypes.put(typeParameters[i], actualTypeArguments[i]); } } else { return ImmutableList.of(); } // we can stop if we have reached the sought for base type if (base.equals(getClass(type))) break; toCheck.add(clazz.getGenericSuperclass()); } // finally, for each actual type argument provided to baseClass, // determine (if possible) the raw class for that type argument. Type[] actualTypeArguments; if (type instanceof Class) { actualTypeArguments = ((Class) type).getTypeParameters(); } else { actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments(); } List<Class<?>> typeArgumentsAsClasses = new ArrayList<Class<?>>(); // resolve types by chasing down type variables. for (Type baseType : actualTypeArguments) { while (resolvedTypes.containsKey(baseType)) { baseType = resolvedTypes.get(baseType); } typeArgumentsAsClasses.add(getClass(baseType)); } return typeArgumentsAsClasses; }
protected void _resolveBindings(Type t) { if (t == null) return; Class<?> raw; if (t instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) t; Type[] args = pt.getActualTypeArguments(); if (args != null && args.length > 0) { Class<?> rawType = (Class<?>) pt.getRawType(); TypeVariable<?>[] vars = rawType.getTypeParameters(); if (vars.length != args.length) { throw new IllegalArgumentException( "Strange parametrized type (in class " + rawType.getName() + "): number of type arguments != number of type parameters (" + args.length + " vs " + vars.length + ")"); } for (int i = 0, len = args.length; i < len; ++i) { TypeVariable<?> var = vars[i]; String name = var.getName(); if (_bindings == null) { _bindings = new LinkedHashMap<String, JavaType>(); } else { /* 24-Mar-2010, tatu: Better ensure that we do not overwrite something * collected earlier (since we descend towards super-classes): */ if (_bindings.containsKey(name)) continue; } // first: add a placeholder to prevent infinite loops _addPlaceholder(name); // then resolve type _bindings.put(name, _typeFactory._constructType(args[i], this)); } } raw = (Class<?>) pt.getRawType(); } else if (t instanceof Class<?>) { raw = (Class<?>) t; /* [JACKSON-677]: If this is an inner class then the generics are defined on the * enclosing class so we have to check there as well. We don't * need to call getEnclosingClass since anonymous classes declare * generics */ _resolveBindings(raw.getDeclaringClass()); /* 24-Mar-2010, tatu: Can not have true generics definitions, but can * have lower bounds ("<T extends BeanBase>") in declaration itself */ TypeVariable<?>[] vars = raw.getTypeParameters(); if (vars != null && vars.length > 0) { JavaType[] typeParams = null; if (_contextType != null && raw.isAssignableFrom(_contextType.getRawClass())) { typeParams = _typeFactory.findTypeParameters(_contextType, raw); } for (int i = 0; i < vars.length; i++) { TypeVariable<?> var = vars[i]; String name = var.getName(); Type varType = var.getBounds()[0]; if (varType != null) { if (_bindings == null) { _bindings = new LinkedHashMap<String, JavaType>(); } else { // and no overwriting... if (_bindings.containsKey(name)) continue; } _addPlaceholder(name); // to prevent infinite loops if (typeParams != null) { _bindings.put(name, typeParams[i]); } else { _bindings.put(name, _typeFactory._constructType(varType, this)); } } } } } else { // probably can't be any of these... so let's skip for now // if (type instanceof GenericArrayType) { // if (type instanceof TypeVariable<?>) { // if (type instanceof WildcardType) { return; } // but even if it's not a parameterized type, its super types may be: _resolveBindings(raw.getGenericSuperclass()); for (Type intType : raw.getGenericInterfaces()) { _resolveBindings(intType); } }
@Override public Class<?> rawType() { return (Class<?>) parameterizedType.getRawType(); }
private void readActualTypeParameters() { registerTypeVariablesOn(parameterizedType.getRawType()); registerTypeVariablesOn(parameterizedType); }