/** Create {@link JavaType} based on {@link AnnotatedType} instance. */ public static JavaType of(AnnotatedType annotatedType) { if (annotatedType instanceof AnnotatedArrayType) { return JavaTypes.of((AnnotatedArrayType) annotatedType); } if (annotatedType instanceof AnnotatedParameterizedType) { return JavaTypes.of((AnnotatedParameterizedType) annotatedType); } if (annotatedType instanceof AnnotatedTypeVariable) { return JavaTypes.of((AnnotatedTypeVariable) annotatedType); } if (annotatedType instanceof AnnotatedWildcardType) { return JavaTypes.of((AnnotatedWildcardType) annotatedType); } // default case: use underlying raw type JavaType result = of(annotatedType.getType()); result.getAnnotations().addAll(Annotation.of(annotatedType.getAnnotations())); return result; }
public AnnotatedType getMappableType(AnnotatedType type) { InputConverter converter = this.getInputConverter(type); if (converter != null) { return getMappableType(converter.getSubstituteType(type)); } if (type.getType() instanceof Class) { return type; } if (type instanceof AnnotatedParameterizedType) { AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) type; AnnotatedType[] arguments = Arrays.stream(parameterizedType.getAnnotatedActualTypeArguments()) .map(this::getMappableType) .toArray(AnnotatedType[]::new); return TypeFactory.parameterizedAnnotatedClass(GenericTypeReflector.erase(type.getType()), type.getAnnotations(), arguments); } throw new IllegalArgumentException("Can not deserialize type: " + type.getType().getTypeName()); }
public static boolean containsTypeAnnotation(AnnotatedType type, Class<? extends Annotation> annotation) { if (type.isAnnotationPresent(annotation)) { return true; } if (type instanceof AnnotatedParameterizedType) { AnnotatedParameterizedType parameterizedType = ((AnnotatedParameterizedType) type); return Arrays.stream(parameterizedType.getAnnotatedActualTypeArguments()) .anyMatch(param -> containsTypeAnnotation(param, annotation)); } if (type instanceof AnnotatedTypeVariable) { AnnotatedTypeVariable variable = ((AnnotatedTypeVariable) type); return Arrays.stream(variable.getAnnotatedBounds()) .anyMatch(bound -> containsTypeAnnotation(bound, annotation)); } if (type instanceof AnnotatedWildcardType) { AnnotatedWildcardType wildcard = ((AnnotatedWildcardType) type); return Stream.concat( Arrays.stream(wildcard.getAnnotatedLowerBounds()), Arrays.stream(wildcard.getAnnotatedUpperBounds())) .anyMatch(param -> containsTypeAnnotation(param, annotation)); } if (type instanceof AnnotatedArrayType) { return containsTypeAnnotation(((AnnotatedArrayType) type).getAnnotatedGenericComponentType(), annotation); } return false; }
public MinijaxPropertyDescriptor(final Class<?> elementClass, final AnnotatedType annotatedType, final Annotation[] annotations) { super(elementClass, buildConstraintDescriptors(annotatedType, annotations)); if (annotatedType instanceof AnnotatedParameterizedType) { constrainedContainerElementTypes = MinijaxContainerElementTypeDescriptor.build(elementClass, (AnnotatedParameterizedType) annotatedType); } else { constrainedContainerElementTypes = emptySet(); } }
public static Set<ContainerElementTypeDescriptor> build( final Class<?> elementClass, final AnnotatedParameterizedType annotatedType) { final Set<ContainerElementTypeDescriptor> result = new HashSet<>(); final Class<?> containerClass = ReflectionUtils.getRawType(annotatedType); int argIndex = 0; for (final AnnotatedType typeArg : annotatedType.getAnnotatedActualTypeArguments()) { final Set<ConstraintDescriptor<?>> constraintDescriptors = new HashSet<>(); for (final Annotation annotation : typeArg.getAnnotations()) { final MinijaxConstraintDescriptor<?> constraintDescriptor = MinijaxConstraintDescriptor.build(typeArg, annotation); if (constraintDescriptor != null) { constraintDescriptors.add(constraintDescriptor); } } if (!constraintDescriptors.isEmpty()) { result.add(new MinijaxContainerElementTypeDescriptor(elementClass, containerClass, argIndex, constraintDescriptors)); } argIndex++; } return result; }
private void verifyMapFieldTypeAnnotations(Class c) throws NoSuchFieldException, NoSuchMethodException { Annotation anno; AnnotatedType atBase; AnnotatedType atParameter; atBase = c.getDeclaredField("typeAnnotatedMap").getAnnotatedType(); anno = atBase.getAnnotations()[0]; verifyTestAnn(mapTA[0], anno, "map1"); mapTA[0] = anno; atParameter = ((AnnotatedParameterizedType) atBase). getAnnotatedActualTypeArguments()[0]; anno = ((AnnotatedWildcardType) atParameter).getAnnotations()[0]; verifyTestAnn(mapTA[1], anno, "map2"); mapTA[1] = anno; anno = ((AnnotatedWildcardType) atParameter). getAnnotatedUpperBounds()[0].getAnnotations()[0]; verifyTestAnn(mapTA[2], anno, "map3"); mapTA[2] = anno; atParameter = ((AnnotatedParameterizedType) atBase). getAnnotatedActualTypeArguments()[1]; anno = ((AnnotatedParameterizedType) atParameter).getAnnotations()[0]; verifyTestAnn(mapTA[3], anno, "map4"); mapTA[3] = anno; anno = ((AnnotatedParameterizedType) atParameter). getAnnotatedActualTypeArguments()[0].getAnnotations()[0]; verifyTestAnn(mapTA[4], anno, "map5"); mapTA[4] = anno; }
public void checkAnnotations(AnnotatedType type, String expected) { String actual = Arrays.asList(((AnnotatedParameterizedType) type) .getAnnotations()) .toString() + "," + Arrays.asList(((AnnotatedParameterizedType) type) .getAnnotatedActualTypeArguments()[0].getAnnotations()) .toString(); if (!actual.equals(expected)) throw new AssertionError("Unexpected annotations" + actual); }
/** Create {@link JavaType} based on {@link AnnotatedParameterizedType} instance. */ static JavaType of(AnnotatedParameterizedType annotatedType) { List<TypeArgument> arguments = new ArrayList<>(); for (AnnotatedType actual : annotatedType.getAnnotatedActualTypeArguments()) { arguments.add(TypeArgument.of(JavaType.of(actual))); } ParameterizedType pt = (ParameterizedType) annotatedType.getType(); ClassType result = (ClassType) JavaType.of(pt.getRawType()); result.getAnnotations().addAll(Annotation.of(annotatedType.getAnnotations())); result.getTypeArguments().addAll(arguments); return result; }
@Override public String generateTypeName(AnnotatedType type) { if (type instanceof AnnotatedParameterizedType) { String baseName = generateSimpleName(type); StringBuilder genericName = new StringBuilder(baseName); Arrays.stream(((AnnotatedParameterizedType) type).getAnnotatedActualTypeArguments()) .map(this::generateSimpleName) .forEach(argName -> genericName.append("_").append(argName)); return genericName.toString(); } return generateSimpleName(type); }
@Override public String rawName() { if (annotatedType instanceof AnnotatedParameterizedType) { return ((ParameterizedType)(annotatedType.getType())).getRawType().getTypeName(); } else { return null; } }
@Override public GraphQLOutputType toGraphQLType(AnnotatedType javaType, Set<Type> abstractTypes, OperationMapper operationMapper, BuildContext buildContext) { GraphQLUnion annotation = javaType.getAnnotation(GraphQLUnion.class); List<AnnotatedType> possibleJavaTypes = Arrays.asList(((AnnotatedParameterizedType) javaType).getAnnotatedActualTypeArguments()); return toGraphQLUnion(annotation.name(), annotation.description(), javaType, possibleJavaTypes, abstractTypes, operationMapper, buildContext); }
public static AnnotatedType unionize(AnnotatedType[] types) { Objects.requireNonNull(types); if (types.length < 2) { if (types.length == 1 && GenericTypeReflector.isSuperType(Union.class, types[0].getType())) { return types[0]; } throw new IllegalArgumentException(SINGLE_TYPE_UNION_ERROR); } AnnotatedType t1 = types[0]; if (stream(types).anyMatch(t -> t.isAnnotationPresent(GraphQLUnion.class))) { if (stream(types).allMatch(t -> t.isAnnotationPresent(GraphQLUnion.class) && t.getAnnotation(GraphQLUnion.class).name().equals(t1.getAnnotation(GraphQLUnion.class).name()))) { return of(types); } else { throw new IllegalArgumentException("All union members must be explicitly annotated: " + Arrays.toString(types)); } } if (stream(types).allMatch(t -> t instanceof AnnotatedParameterizedType)) { AnnotatedParameterizedType p1 = (AnnotatedParameterizedType) t1; AnnotatedParameterizedType[] pTypes = stream(types) .map(t -> (AnnotatedParameterizedType) t) .toArray(AnnotatedParameterizedType[]::new); AnnotatedType[] params = new AnnotatedType[p1.getAnnotatedActualTypeArguments().length]; for (int i = 0; i < p1.getAnnotatedActualTypeArguments().length; i++) { final int j = i; params[i] = unionize(stream(pTypes) .map(p -> p.getAnnotatedActualTypeArguments()[j]) .toArray(AnnotatedType[]::new)); } Class<?> rawType = ((Class<?>) ((ParameterizedType) p1.getType()).getRawType()); return TypeFactory.parameterizedAnnotatedClass(rawType, ClassUtils.getAllAnnotations(stream(types)), params); } if (stream(types).allMatch(t -> t instanceof AnnotatedArrayType)) { AnnotatedType[] components = stream(types) .map(type -> ((AnnotatedArrayType) type).getAnnotatedGenericComponentType()) .toArray(AnnotatedType[]::new); return TypeFactory.arrayOf(unionize(components), ClassUtils.getAllAnnotations(stream(types))); } if (stream(types).allMatch(t -> types[0].getType().equals(t.getType()))) { return types[0]; } throw new IllegalArgumentException("Types are incompatible and can not be unionized: "); }
private static AnnotatedType getCommonSuperType(List<AnnotatedType> types, Set<String> seenTypeCombos, AnnotatedType fallback) { if (types == null || types.isEmpty()) { throw new IllegalArgumentException("At least one type must be provided"); } if (types.size() == 1) { return types.get(0); } Annotation[] mergedAnnotations = getMergedAnnotations(types.toArray(new AnnotatedType[types.size()])); if (types.stream().map(AnnotatedType::getType).allMatch(type -> type.equals(types.get(0).getType()))) { return GenericTypeReflector.replaceAnnotations(types.get(0), mergedAnnotations); } List<Class<?>> classes = types.stream().map(AnnotatedType::getType).map(ClassUtils::getRawType).collect(Collectors.toList()); String typeNames = types.stream().map(type -> type.getType().getTypeName()).sorted().collect(Collectors.joining(",")); if (seenTypeCombos.contains(typeNames)) { return fallbackOrException(fallback); } seenTypeCombos.add(typeNames); //deal with arrays first as they are special if (types.stream().allMatch(type -> type instanceof AnnotatedArrayType)) { List<AnnotatedType> componentTypes = types.stream() .map(type -> ((AnnotatedArrayType) type).getAnnotatedGenericComponentType()) .collect(Collectors.toList()); AnnotatedType componentType = getCommonSuperType(componentTypes, seenTypeCombos, fallback); return TypeFactory.arrayOf(componentType, mergedAnnotations); } Class<?> commonRawSuperType = getCommonSuperTypes(classes).get(0); if (classes.stream().noneMatch(ROOT_TYPES::contains) && ROOT_TYPES.contains(commonRawSuperType)) { return fallbackOrException(fallback); } List<AnnotatedType> normalizedTypes = types.stream() .map(type -> GenericTypeReflector.getExactSuperType(type, commonRawSuperType)) .collect(Collectors.toList()); if (normalizedTypes.stream().anyMatch(type -> GenericTypeReflector.isMissingTypeParameters(type.getType()))) { throw new TypeMappingException("Automatic type inference failed because some of the types are missing generic type parameter(s)."); } if (normalizedTypes.stream().allMatch(type -> type.getType() instanceof Class)) { return annotate(commonRawSuperType, mergedAnnotations); } if (normalizedTypes.stream().allMatch(type -> type instanceof AnnotatedParameterizedType)) { AnnotatedType[] parameters = Arrays.stream(commonRawSuperType.getTypeParameters()) .map(param -> normalizedTypes.stream().map(type -> GenericTypeReflector.getTypeParameter(type, param)).collect(Collectors.toList())) .map(paramTypes -> getCommonSuperType(paramTypes, seenTypeCombos, fallback)) .toArray(AnnotatedType[]::new); return TypeFactory.parameterizedAnnotatedClass(commonRawSuperType, mergedAnnotations, parameters); } return fallbackOrException(fallback); }
public static <T> TypedClass<T> wrap(AnnotatedType ant) { if (ant instanceof AnnotatedParameterizedType) { AnnotatedParameterizedType pant = (AnnotatedParameterizedType) ant; ParameterizedType pt = (ParameterizedType) ant.getType(); return (TypedClass<T>) wrap(wrapSimple(pt.getRawType()), pant.getAnnotatedActualTypeArguments(), pt, ant.getAnnotations()); } else if (ant instanceof AnnotatedArrayType) { AnnotatedArrayType aant = (AnnotatedArrayType) ant; TypedClass<?> ctype = wrap(aant.getAnnotatedGenericComponentType()); return new TypedArrayClass<>(ctype, ant.getAnnotations()); } return wrap(ant.getType(), ant.getDeclaredAnnotations()); }
/** * Given an input class, finds the usage of 'wanted', and returns the * annotated type number of param. */ public static AnnotatedType getParamterOfInterface(Class<?> klass, Class<?> wanted, int param) { final AnnotatedType val = TypeUtils.getInterfaceType(klass, wanted); if (val == null) { // no base class implements the given interface return null; } // if (!(val instanceof AnnotatedParameterizedType)) { throw new IllegalArgumentException("is not a parameterized type"); } final AnnotatedParameterizedType ptype = (AnnotatedParameterizedType) val; if (param >= ptype.getAnnotatedActualTypeArguments().length) { throw new IllegalArgumentException("too many"); } return ptype.getAnnotatedActualTypeArguments()[param]; }
AnnotatedParameterizedType get(String name) throws NoSuchMethodException, SecurityException { Method method = MyTestClass.class.getMethod(name); return (AnnotatedParameterizedType) method.getAnnotatedReturnType(); }
/** * Finds and return mapper by type. Uses registered mappers map if not null to search for candidates and register results in this map. */ @Nullable public static <T> DbMapper<T> findOrResolveMapperByType(@NotNull Class<T> type, @Nullable Map<Class, DbMapper> registeredMappers) { DbMapper<T> mapper = registeredMappers == null ? null : registeredMappers.get(type); if (mapper == null) { // search for a field marked as mapper with valid parameter type for (Field f : type.getDeclaredFields()) { int mods = f.getModifiers(); if (Modifier.isStatic(mods) && Modifier.isPublic(mods) && Modifier.isFinal(mods) && f.getType().isAssignableFrom(DbMapper.class)) { AnnotatedType at = f.getAnnotatedType(); if (at instanceof AnnotatedParameterizedType) { AnnotatedParameterizedType apt = (AnnotatedParameterizedType) at; AnnotatedType[] args = apt.getAnnotatedActualTypeArguments(); if (args.length == 1 && args[0].getType() == type) { Mapper a = f.getAnnotation(Mapper.class); if (a != null) { try { //noinspection unchecked mapper = (DbMapper<T>) f.get(type); if (mapper == null) { throw new IllegalArgumentException("Mapper must not be null: " + f); } } catch (IllegalAccessException ignored) { // already checked for 'isPublic' before } if (registeredMappers != null) { if (registeredMappers.containsKey(type)) { throw new IllegalArgumentException("Found multiple mappers per type: m1: " + mapper + ", m2: " + registeredMappers.get(type)); } registeredMappers.put(type, mapper); } } } } } else { if (f.getAnnotation(Mapper.class) != null) { throw new IllegalArgumentException("@Mapper field must be public, static final and have valid parametrized type type: " + f); } } } } return mapper; }
public TypeInternal getArgAt(int index) { AnnotatedParameterizedType annotatedParameterizedType = (AnnotatedParameterizedType) annotatedType; return new ReflectType(annotatedParameterizedType.getAnnotatedActualTypeArguments()[index]); }