@Bean() public static CodecRegistry getCodecRegistry() { return CodecRegistries.fromRegistries( CodecRegistries.fromProviders( new EnumCodecProvider(), PojoCodecProvider.builder() .register(CodecResolverTest.class) .registerCodecResolver((CodecResolver) (type, typeCodecRegistry, codecConfiguration) -> { if (TypeUtils.isAssignable(type, Base.class)) { return new DocumentCodec((Class<? extends Base>) type, typeCodecRegistry, codecConfiguration); } return null; }) .build() ), MongoClient.getDefaultCodecRegistry()); }
/** * Return the type of the content of the given collection type. * * @param type The collection type. * @return Collection type. */ public static Class<?> getCollectionType(Type type) { if (TypeUtils.isAssignable(type, Collection.class)) { if (type instanceof ParameterizedType) { Type genericType = ((ParameterizedType) type).getActualTypeArguments()[0]; if (genericType instanceof Class) { return (Class<?>) genericType; } } else { throw new IllegalArgumentException("Cannot infer index type for non-parameterized type: " + type); } } else if (TypeUtils.isArrayType(type)) { return (Class<?>) TypeUtils.getArrayComponentType(type); } throw new IllegalArgumentException("Unsupported type: " + type); }
private static Signature createSignature(final Object input, final Type type, final Map<TypeVariable<?>, Type> typeArgs, final boolean isInput) { final Class clazz = getTypeClass(type, typeArgs); if (Tuple.class.isAssignableFrom(clazz)) { final TypeVariable[] tupleTypes = getTypeClass(type, typeArgs).getTypeParameters(); final Map<TypeVariable<?>, Type> classTypeArgs = TypeUtils.getTypeArguments(type, clazz); Collection<? extends Type> types = TypeUtils.getTypeArguments(type, clazz).values(); Class[] classes = new Class[types.size()]; int i = 0; for (final TypeVariable tupleType : tupleTypes) { classes[i++] = getTypeClass(classTypeArgs.get(tupleType), typeArgs); } return new TupleSignature(input, clazz, classes, isInput); } return new SingletonSignature(input, clazz, isInput); }
@Override public T generateIdIfAbsentFromDocument(T document) { if (idGenerator != null && !documentHasId(document)) { Object generatedId = idGenerator.generate(); try { if (!idField.setFieldValue(document, generatedId)) { LOGGER.error("Id {} for pojo {} could not be set. Please watch the logs.", generatedId, document); throw new IdGenerationException("Id could not be generated for pojo. See logs for details."); } } catch (TypeMismatchException e) { if (generatedId != null && !TypeUtils.isAssignable(generatedId.getClass(), idField.fieldTypePair.realType)) { LOGGER.error("Your set id generator {} for the id field {} produces non-assignable values.", idGenerator, idField, e); } else { LOGGER.error("Some unspecified error occurred while generating an id {} for your pojo {}", generatedId, document); } throw new IdGenerationException("Id could not be generated for pojo. See logs for details.", e); } } return document; }
/** * If the requested type is not registered within the class hierarchy it may still be persistable if a superclass is * registered. But then we need to find the type that is in the set of registered types. * * @param type * @param classHierarchyNodeForType * @return */ private Type downGradeType(Type type, ClassHierarchyNode classHierarchyNodeForType) { if (classHierarchyNodeForType == null) { return type; } Class<?> clazz = classHierarchyNodeForType.getClazz(); // if the type is directly assignable, we can simply return the type if (TypeUtils.isAssignable(clazz, type)) { return type; } // now we need to downgrade type to clazz if (clazz.getTypeParameters().length > 0) { //if clazz has type parameters, we need to figure out the correct types // TODO encoding with specific type arguments may work, but decoding into // TODO the type (that is within the group of registered classes) would loose information, so maybe // we should not try to infer the type arguments? return TypeUtils.parameterize(clazz, TypeUtils.getTypeArguments(type, clazz)); } else { return clazz; } }
/** * Assume the following class declaration: * <pre> * {@code * static class AList<P1, P2 extends Map<P1, Long>> implements AInterface<P1> {} * } * </pre> * <p> * For a given clazzTypeParameter ({@link TypeVariable} P1) and the map P1 -> Integer.class * a new Type {@code Integer} is returned. * <p> * For a given clazzTypeParameter ({@link TypeVariable} P2) and the map P1 -> Integer.class * a new Type {@code Map<Integer, Long>} is returned. * * @param clazzTypeParameter The TypeVariable of a given class * @param superClassTypeMap the map of resolved values * @return a recursively resolved type */ private static Type inferRealType(Type clazzTypeParameter, Map<String, Type> superClassTypeMap) { if (clazzTypeParameter instanceof ParameterizedType) { ParameterizedType bound = (ParameterizedType) clazzTypeParameter; List<Type> typeList = new ArrayList<>(); for (int i = 0; i < bound.getActualTypeArguments().length; i++) { typeList.add(inferRealType(bound.getActualTypeArguments()[i], superClassTypeMap)); } return TypeUtils.parameterizeWithOwner(bound.getOwnerType(), (Class<?>) bound.getRawType(), typeList.toArray(new Type[0])); } else if (clazzTypeParameter instanceof TypeVariable) { TypeVariable typeVariable = (TypeVariable) clazzTypeParameter; Type newType = superClassTypeMap.get(typeVariable.getName()); if (newType != null) { return newType; } else { return inferRealType(typeVariable.getBounds()[0], superClassTypeMap); } } return clazzTypeParameter; }
/** * Iterates over the list of codecResolvers and returns a PolymorphicCodec if match is found. * Codecs eligible to encode/decode sub classes of polymorphic structures need to provide special functionality and * can be registered during setup of the PojoCodecProvider {@link PojoCodecProvider.Builder#registerCodecResolver(CodecResolver[])} * * @param type the value type * @param typeCodecRegistry codec registry that can handle any type including parameterizd types, generic arrays, etc * @return ReflectionCodec if responsible resolver si found */ public synchronized <T> PolymorphicCodec<T> resolve(Type type, TypeCodecRegistry typeCodecRegistry) { PolymorphicCodec<T> codec; for (CodecResolver codecResolver : codecResolvers) { codec = codecResolver.getCodec(type, typeCodecRegistry, codecConfiguration); if (codec != null) { return codec; } } // enums are special - a PolymorphicCodec for enums can be build on the fly {@link EnumReflectionCodecWrapper} if (TypeUtils.isAssignable(type, Enum.class)) { return new EnumReflectionCodecWrapper(typeCodecRegistry.getCodec(type)); } // fallback is BasicReflectionCodec return new BasicReflectionCodec(type, typeCodecRegistry, codecConfiguration); }
@Test public void downGradeTypeTest() { TypesModel typesModel = new TypesModel(new HashSet<>( Arrays.asList( ModelClassBase.class, ModelClassWithTypeParameter.class, ModelClassWithoutTypeParameter.class )), null, null); assertThat(typesModel.getAssignableTypesWithinClassHierarchy(NonModelClassWithoutTypeParameter.class), IsIterableContainingInAnyOrder.containsInAnyOrder(ModelClassWithoutTypeParameter.class)); assertThat(typesModel.getAssignableTypesWithinClassHierarchy(TypeUtils.parameterize(NonModelClassWithTypeParameter.class, Float.class)), IsIterableContainingInAnyOrder.containsInAnyOrder( TypeUtils.parameterize(ModelClassWithTypeParameter.class, Float.class, Date.class))); assertThat(typesModel.getAssignableTypesWithinClassHierarchy(NonModelClassWithoutTypeParameterExtendingModelClassWithTypeParameter.class), IsIterableContainingInAnyOrder.containsInAnyOrder( TypeUtils.parameterize(ModelClassWithTypeParameter.class, BigInteger.class, Date.class))); assertThat(typesModel.getAssignableTypesWithinClassHierarchy(NonModelClassWithTypeParameterExtendingNonModelClass.class), IsIterableContainingInAnyOrder.containsInAnyOrder( TypeUtils.parameterize(ModelClassWithTypeParameter.class, Float.class, Date.class))); }
@Test public void getAssignableTypesWithinClassHierarchy() throws Exception { assertThat(typesModel.getAssignableTypesWithinClassHierarchy(TypeUtils.parameterize(A.class, Integer.class)), IsIterableContainingInAnyOrder.containsInAnyOrder( TypeUtils.parameterize(A.class, Integer.class))); assertThat(typesModel.getAssignableTypesWithinClassHierarchy(TypeUtils.parameterize(XY.class, Float.class)), IsIterableContainingInAnyOrder.containsInAnyOrder( TypeUtils.parameterize(A.class, Float.class))); assertThat(typesModel.getAssignableTypesWithinClassHierarchy(TypeUtils.parameterize(XY.class, Integer.class)), IsIterableContainingInAnyOrder.containsInAnyOrder( TypeUtils.parameterize(A.class, Integer.class), AAX.class)); assertThat(typesModel.getAssignableTypesWithinClassHierarchy(TypeUtils.parameterize(XY.class, BigInteger.class)), IsIterableContainingInAnyOrder.containsInAnyOrder( TypeUtils.parameterize(A.class, BigInteger.class), TypeUtils.parameterize(AA.class, BigInteger.class), AAB.class, AAA.class, ABX.class, AAAA.class)); }
@Bean() public static CodecRegistry getCodecRegistry() { return CodecRegistries.fromRegistries( CodecRegistries.fromProviders( new EnumCodecProvider(), PojoCodecProvider.builder() .register(Pojo.class.getPackage().getName()) .registerCodecResolver((CodecResolver) (type, typeCodecRegistry, codecConfiguration) -> { if (TypeUtils.isAssignable(type, CustomId.class)) { return new CustomIdCodec((Class<CustomId>)type, typeCodecRegistry, codecConfiguration); } return null; }).build() ), MongoClient.getDefaultCodecRegistry()); }
private Class<? extends Throwable> getGenericType(Class<? extends JsonApiExceptionMapper> mapper) { Type[] types = mapper.getGenericInterfaces(); if (null == types || 0 == types.length ){ types = new Type[]{mapper.getGenericSuperclass()}; } for (Type type : types) { if (type instanceof ParameterizedType && (TypeUtils.isAssignable(((ParameterizedType) type).getRawType(),JsonApiExceptionMapper.class) || TypeUtils.isAssignable(((ParameterizedType) type).getRawType(),ExceptionMapper.class))) { //noinspection unchecked return (Class<? extends Throwable>) ((ParameterizedType) type).getActualTypeArguments()[0]; } } //Won't get in here return null; }
public static void main(String[] args) throws InstantiationException, IllegalAccessException { int[] a = new int[20]; Class clazz = a.getClass(); // System.out.println(clazz.newInstance()); System.out.println(clazz.isArray()); System.out.println(TypeUtils.getArrayComponentType(clazz)); System.out.println(clazz); Object arr = Array.newInstance(clazz.getComponentType(), 20); System.out.println(arr); List<Integer> d = new ArrayList<>(); clazz = d.getClass(); System.out.println(d.getClass().getGenericSuperclass()); System.out.println(d.getClass().getGenericInterfaces()[0]); ParameterizedType t = (ParameterizedType) clazz.getGenericSuperclass(); System.out.println(t.getActualTypeArguments()[0]); }
private void calculateExactType(ParameterizedType type) { logger.info("Calculating exact tyep for parameterized type " + type); Class<?> rawClass = GenericTypeReflector.erase(type); Type exactType = type; for (VariableReference var : typeMap.get(type)) { ParameterizedType currentType = (ParameterizedType) var.getType(); logger.info("Assigned variable of type: " + currentType); Type candidateType = GenericTypeReflector.getExactSuperType(currentType, rawClass); logger.info("Resulting type: " + candidateType); if (TypeUtils.isAssignable(candidateType, exactType)) { exactType = candidateType; } } logger.info("Result: " + exactType); }
@SuppressWarnings("unchecked") private <T> void registerAggregateFactories( final RegistrableAggregateSnaphotter snapshotter) { Set<Annotation> qualifiers = ImmutableSet.copyOf(getQualifiers()); for (AggregateRootInfo aggregateRoot : aggregateRootsInfo) { if (aggregateRoot.matchQualifiers(QualifierType.SNAPSHOTTER, qualifiers)) { Set<Annotation> factoryQualifiers = aggregateRoot .getQualifiers(QualifierType.REPOSITORY); Type type = TypeUtils.parameterize(EventSourcingRepository.class, aggregateRoot.getType()); EventSourcingRepository<T> repository = (EventSourcingRepository<T>) CdiUtils .getReference(getBeanManager(), type, factoryQualifiers); if (repository != null) { snapshotter.registerAggregateFactory(repository.getAggregateFactory()); } new EventCountSnapshotTriggerDefinition(snapshotter, 10); } } }
@SuppressWarnings({ "unchecked" }) protected <T> void registerRepositories(X commandBus) { final Set<Annotation> qualifiers = ImmutableSet.copyOf(getQualifiers()); for (AggregateRootInfo aggregateRootInfo : aggregateRootsInfo) { if (aggregateRootInfo.matchQualifiers(QualifierType.COMMAND_BUS, qualifiers)) { Class<T> aggregateType = (Class<T>) aggregateRootInfo.getType(); ParameterizedType repositoryType = TypeUtils.parameterize(EventSourcingRepository.class, aggregateType); EventSourcingRepository<T> repository = (EventSourcingRepository<T>) CdiUtils.getReference( getBeanManager(), repositoryType, aggregateRootInfo.getQualifiers(QualifierType.REPOSITORY)); AggregateAnnotationCommandHandler<?> aggregateAnnotationCommandHandler = new AggregateAnnotationCommandHandler<>(aggregateType, repository); aggregateAnnotationCommandHandler.subscribe(commandBus); if (commandBus instanceof DisruptorCommandBus) { ((DisruptorCommandBus) commandBus).createRepository(repository.getAggregateFactory()); } } } }
/** * Checks that the actual field is parameterized. * * @param expectedRawType the expected raw type * @param expectedTypeArguments the expected type arguments * @return this {@link FieldAssertion} for fluent linking */ public FieldAssertion isParameterizedType(final Class<?> expectedRawType, final Type... expectedTypeArguments) { isNotNull(); if (!(actual.getGenericType() instanceof ParameterizedType)) { failWithMessage("Expected field <%s> to be a parameterized type but it was not", actual); } final ParameterizedType actualType = (ParameterizedType) actual.getGenericType(); final ParameterizedType expectedParameterizedType = TypeUtils.parameterize(expectedRawType, expectedTypeArguments); if (!TypeUtils.equals(actualType, expectedParameterizedType)) { failWithMessage("Expected field %s.%s to be of type %s<%s> but it was %s<%s>", actual.getType().getName(), actual.getName(), expectedRawType, expectedTypeArguments, actualType.getRawType().getTypeName(), actualType.getActualTypeArguments()); } return this; }
@Override public List<Parameter> extractParameters(List<Annotation> annotations, Type type, Set<Type> typesToSkip, Iterator<SwaggerExtension> chain) { Class<?> cls = TypeUtils.getRawType(type, type); List<Parameter> output = new ArrayList<Parameter>(); if (shouldIgnoreClass(cls) || typesToSkip.contains(type)) { // stop the processing chain typesToSkip.add(type); return output; } for (Annotation annotation : annotations) { if (annotation instanceof BeanParam || annotation instanceof InjectParam) { return extractParameters(cls); } } if (chain.hasNext()) { return chain.next().extractParameters(annotations, type, typesToSkip, chain); } return Collections.emptyList(); }
protected Converter findAssignable(Type src, Type target) { if (TypeUtils.isAssignable(src, target)) { return same; } return null; }
public static <T> T convertWithConstructor(Map<String,Sheet> sheetMap, Class<T> clazz, boolean hasHeader) throws IllegalAccessException, InstantiationException, InvocationTargetException { // T object = (T) UnsafeUtil.getUnsafe().allocateInstance(clazz); T object = clazz.newInstance(); //可能没有无参构造方法 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if(field.isAnnotationPresent(ExcelSheetField.class)){ ExcelSheetField annotation = field.getAnnotation(ExcelSheetField.class); Sheet sheet = sheetMap.get(annotation.name()); if(sheet == null) continue; Iterator<Row> iterator = sheet.iterator(); Class type = field.getType(); boolean isList = type.isAssignableFrom(List.class); if(isList){ type = TypeUtils.getRawType(((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0],null); } List<T> list = convertWithConstructor(iterator, type, hasHeader); if (isList) { setMethod(field, clazz).invoke(object, list); } else { if(CollectionUtils.isNotEmpty(list)){ setMethod(field, clazz).invoke(object, list.get(0)); } } } } return object; }
private static void getFieldTypePairsRecursive(final Type type, final boolean returnFinalFields, List<FieldTypePair> currentList, Map<String, Type> realTypeMap) { if (type instanceof ParameterizedType) { getFieldTypePairsRecursive((ParameterizedType) type, returnFinalFields, currentList, realTypeMap); } else if (type instanceof Class) { getFieldTypePairsRecursive(TypeUtils.parameterize((Class) type, ((Class) type).getTypeParameters()), returnFinalFields, currentList, realTypeMap); } else if (type instanceof WildcardType) { WildcardType wildcardType = (WildcardType) type; Type upperBoundType = wildcardType.getUpperBounds()[0]; getFieldTypePairsRecursive(upperBoundType, returnFinalFields, currentList, realTypeMap); } else { throw new IllegalArgumentException("Unknown type." + type); } }
public static Type inferRealType(Type type, Map<String, Type> realTypeMap) { if (type instanceof GenericArrayType) { GenericArrayType genericArrayType = (GenericArrayType) type; Type genericComponentType = genericArrayType.getGenericComponentType(); return TypeUtils.genericArrayType(inferRealType(genericComponentType, realTypeMap)); } else if (type instanceof ParameterizedType) { ParameterizedType bound = (ParameterizedType) type; List<Type> typeList = new ArrayList<>(); for (int i = 0; i < bound.getActualTypeArguments().length; i++) { typeList.add(inferRealType(bound.getActualTypeArguments()[i], realTypeMap)); } return TypeUtils.parameterizeWithOwner(bound.getOwnerType(), (Class<?>) bound.getRawType(), typeList.toArray(new Type[0])); } else if (type instanceof WildcardType) { WildcardType wildcardType = (WildcardType) type; return TypeUtils.wildcardType() .withLowerBounds(inferRealTypes(wildcardType.getLowerBounds(), realTypeMap)) .withUpperBounds(inferRealTypes(wildcardType.getUpperBounds(), realTypeMap)).build(); } else if (type instanceof TypeVariable) { if (realTypeMap == null) { return ((TypeVariable) type).getBounds()[0]; } Type typeFoundInMap = realTypeMap.get(type.getTypeName()); if (typeFoundInMap != null) { return typeFoundInMap; } return type; } return type; }
private static void getMethodTypePairsRecursive(final Type type, List<MethodTypePair> currentList, Map<String, Type> realTypeMap) { if (type instanceof ParameterizedType) { getMethodTypePairsRecursive((ParameterizedType) type, currentList, realTypeMap); } else if (type instanceof Class) { getMethodTypePairsRecursive(TypeUtils.parameterize((Class) type, ((Class) type).getTypeParameters()), currentList, realTypeMap); } else { throw new IllegalArgumentException("Unknown type." + type); } }
private static Type findInterface(Type type, Class interfaceToFind, Map<String, Type> realTypeMap) { if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; return findInterface(parameterizedType, interfaceToFind, realTypeMap); } else if (type instanceof Class) { Class clazz = (Class) type; return findInterface(TypeUtils.parameterize(clazz, clazz.getTypeParameters()), interfaceToFind, realTypeMap); } return null; }
/** * @param type type to be examined * @return The raw class of the given type or if type is a class, the class itself will be returned */ public static Class extractRawClass(Type type) { if (type == null) { return null; } return TypeUtils.getRawType(type, null); }
/** * @param type the type for with sub types should be found * @param classHierarchyNode the hierarchy of sub types * @param validTypes a Set of found valid types so far */ private void getAssignableTypesWithinClassHierarchy(Type type, ClassHierarchyNode classHierarchyNode, Set<Type> validTypes) { if (classHierarchyNode != null) { Class<?> clazz = classHierarchyNode.getClazz(); Type matchingType = null; // first check general assignability // this does not mean that the parameterized clazz would be assignable to type since the parameter bounds may be wrong! if (TypeUtils.isAssignable(clazz, type)) { if (type instanceof ParameterizedType) { matchingType = getMatchingType((ParameterizedType) type, clazz); } else { matchingType = clazz; } } if (!clazz.isInterface() && matchingType != null) { validTypes.add(matchingType); } // if type match, walk down children if (matchingType != null) { for (ClassHierarchyNode child : classHierarchyNode.getChildren()) { getAssignableTypesWithinClassHierarchy(matchingType, child, validTypes); } } } }
@Override public <T> Codec<T> get(Type type, TypeCodecRegistry typeCodecRegistry) { // byte arrays are handled well by the mongo java driver if (TypeUtils.isArrayType(type)) { return new ArrayCodec(type, typeCodecRegistry); } else if (type instanceof TypeVariable) { throw new IllegalArgumentException("This registry (and probably no other one as well) can not handle generic type variables."); } else if (type instanceof WildcardType) { LOGGER.error("WildcardTypes are not yet supported. {}", type); throw new NotImplementedException("WildcardTypes are not yet supported. " + type); } // the default codecs provided by the mongo driver lack the decode method, hence this redefinition else if (Float.class.equals(type)) { return (Codec<T>) FLOAT_CODEC; } else if (Short.class.equals(type)) { return (Codec<T>) SHORT_CODEC; } else if (Byte.class.equals(type)) { return (Codec<T>) BYTE_CODEC; } else if (TypeUtils.isAssignable(type, SpecialFieldsMap.class)) { return new SpecialFieldsMapCodec(type, typeCodecRegistry); } // List ? Codec<T> codec = ListTypeCodec.getCodecIfApplicable(type, typeCodecRegistry); if (codec != null) { return codec; } // Set ? codec = SetTypeCodec.getCodecIfApplicable(type, typeCodecRegistry); if (codec != null) { return codec; } // Map ? codec = MapTypeCodec.getCodecIfApplicable(type, typeCodecRegistry); if (codec != null) { return codec; } return null; }
@Override public <T> Codec<T> get(Type type, TypeCodecRegistry typeCodecRegistry) { if (TypeUtils.isAssignable(type, CustomType.class)) { return (Codec<T>) new CustomTypeCodec((ParameterizedType) type, typeCodecRegistry); } return null; }
@Override public <T> Codec<T> get(Type type, TypeCodecRegistry typeCodecRegistry) { if (TypeUtils.isAssignable(type, setOfStringsType)) { return (Codec<T>) new SetOfStringCodec((ParameterizedType) type, typeCodecRegistry); } return null; }
public CustomTypeCodec(ParameterizedType type, TypeCodecRegistry typeCodecRegistry) { Type typeParameter = type.getActualTypeArguments()[0]; this.nameCodec = typeCodecRegistry.getCodec(String.class); this.listCodec = typeCodecRegistry.getCodec(TypeUtils.parameterize(ArrayList.class, typeParameter)); this.innerTypeCodec = typeCodecRegistry.getCodec(ReflectionHelper.getDeclaredAndInheritedFieldTypePair(type, "innerType").getRealType()); this.clazz = ReflectionHelper.extractRawClass(type); }
@Test public void getAssignableTypesWithinClassHierarchyCraz() throws Exception { AInterface<Integer> aInterface = new AList<Integer, Map<Integer, Long>>(); assertThat(typesModel.getAssignableTypesWithinClassHierarchy(TypeUtils.parameterize(AInterface.class, Integer.class)), IsIterableContainingInAnyOrder.containsInAnyOrder( TypeUtils.parameterize(AList.class, Integer.class, TypeUtils.parameterize(Map.class, Integer.class, Long.class)) )); }
@Test public void findInterfaceTest() throws Exception { assertEquals(TypeUtils.parameterize(List.class, Date.class), ReflectionHelper.findInterface(ListOfDates.class, List.class)); assertEquals(TypeUtils.parameterize(List.class, ExtendedValueClass.class), ReflectionHelper.findInterface(SomeSpecializedList.class, List.class)); //maps assertEquals(TypeUtils.parameterize(Map.class, Object.class, Object.class), ReflectionHelper.findInterface(SomeSpecialMap.class, Map.class)); assertEquals(TypeUtils.parameterize(Map.class, String.class, Date.class), ReflectionHelper.findInterface(SomeSpecialMapWithBounds.class, Map.class)); assertEquals(TypeUtils.parameterize(Map.class, String.class, Date.class), ReflectionHelper.findInterface(SomeSpecialMapWithArgumentAndBound.class, Map.class)); }
@Override public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { Type envelopType = TypeUtils.parameterize(ResponseEnvelop.class, type); Converter converter = retrofit.nextResponseBodyConverter(CustomConverterFactory.this, envelopType, annotations); return new ResponseConverter<>(converter); }
public static MethodTracepointSpec getMethodSpec(Class<?> cls, String methodName) throws ClassNotFoundException { MethodTracepointSpec.Builder b = MethodTracepointSpec.newBuilder(); b.setClassName(cls.getName()); b.setMethodName(methodName); Method m = getMethod(cls, methodName); for (Class<?> paramClass : m.getParameterTypes()) { b.addParamClass(paramClass.getCanonicalName()); } int paramCount = 0; for (Type paramType : m.getGenericParameterTypes()) { String paramName = String.format("$%d", ++paramCount); if (TypeUtils.isArrayType(paramType)) { Type arrayOfType = TypeUtils.getArrayComponentType(paramType); String arrayOf = TypeUtils.toString(arrayOfType); b.addAdviceArgBuilder().getMultiBuilder().setLiteral(paramName).setPostProcess("{}") .setType(arrayOf); } else if (TypeUtils.isAssignable(paramType, Collection.class)) { ParameterizedType pt = (ParameterizedType) paramType; Type collectionOfType = pt.getActualTypeArguments()[0]; // doesn't work if multiple type params, but // good enough String collectionOf = TypeUtils.toString(collectionOfType); b.addAdviceArgBuilder().getMultiBuilder().setLiteral(paramName).setPostProcess("{}") .setType(collectionOf); } else { b.addAdviceArgBuilder().setLiteral(paramName); } } return b.build(); }
/** Create a tracepoint for the entry of the named method of the class. * The name of the tracepoint will be the short class name and the method name, * eg java.lang.String.format will have short name String.format * Parameter types will be looked up, and if the method is overloaded, returns one of the methods. * If any of the method arguments are arrays or collections, they will be exported as multi-variables */ public static MethodTracepoint create(Class<?> cls, String methodName, String... namesForMethodParameters) { Where where = Where.ENTRY; String tracepointName = String.format("%s.%s", cls.getSimpleName(), methodName); // Find the method Method m = getMethod(cls, methodName, namesForMethodParameters.length); // Create the tracepoint MethodTracepoint tracepoint = new MethodTracepoint(tracepointName, where, m); // Export the arguments as variables int paramCount = 0; for (Type paramType : m.getGenericParameterTypes()) { String exportAs = namesForMethodParameters[paramCount]; String literal = String.format("$%d", ++paramCount); if (TypeUtils.isArrayType(paramType)) { Type arrayOfType = TypeUtils.getArrayComponentType(paramType); String arrayOf = TypeUtils.toString(arrayOfType); tracepoint.addMultiExport(exportAs, literal, arrayOf); } else if (TypeUtils.isAssignable(paramType, Collection.class)) { ParameterizedType pt = (ParameterizedType) paramType; Type collectionOfType = pt.getActualTypeArguments()[0]; String collectionOf = TypeUtils.toString(collectionOfType); tracepoint.addMultiExport(exportAs, literal, collectionOf); } else { tracepoint.addExport(exportAs, literal); } } return tracepoint; }
/** * Returns the exact return type of the given method in the given type. This * may be different from <tt>m.getGenericReturnType()</tt> when the method * was declared in a superclass, or <tt>type</tt> has a type parameter that * is used in the return type, or <tt>type</tt> is a raw type. */ protected static Type getTypeFromExactReturnType(ParameterizedType returnType, ParameterizedType type) { Map<TypeVariable<?>, Type> typeMap = TypeUtils.getTypeArguments(returnType); Type[] actualParameters = new Type[type.getActualTypeArguments().length]; int num = 0; for (TypeVariable<?> parameterType : ((Class<?>) type.getRawType()).getTypeParameters()) { //for(Type parameterType : type.getActualTypeArguments()) { // if(parameterType instanceof TypeVariable<?>) { boolean replaced = false; for (TypeVariable<?> var : typeMap.keySet()) { // D'oh! Why the heck do we need this?? if (var.getName().equals(parameterType.getName())) { //if(typeMap.containsKey(parameterType)) { actualParameters[num] = typeMap.get(var); replaced = true; break; //} else { } } if (!replaced) { actualParameters[num] = parameterType; } //} // } else { // LoggingUtils.getEvoLogger().info("Not a type variable "+parameterType); // actualParameters[num] = parameterType; // } num++; } return new ParameterizedTypeImpl((Class<?>) type.getRawType(), actualParameters, null); }
/** * <p> * isAssignable * </p> * * @param lhsType * a {@link java.lang.reflect.Type} object. * @param rhsType * a {@link java.lang.reflect.Type} object. * @return a boolean. */ public static boolean isAssignable(Type lhsType, Type rhsType) { if (rhsType == null || lhsType == null) return false; try { return TypeUtils.isAssignable(rhsType, lhsType); } catch (Throwable e) { logger.debug("Found unassignable type: " + e); return false; } }
private void calculateExactType(TypeVariable<?> type) { logger.info("Calculating exact type for typevariable " + type); Type[] bounds = TypeUtils.getImplicitBounds(type); Type exactType = bounds[0]; for (VariableReference var : typeMap.get(type)) { Type candidateType = var.getType(); logger.info("Candidate type: " + candidateType); if (TypeUtils.isAssignable(candidateType, exactType)) { exactType = candidateType; } } logger.info("Result: " + exactType); }
private void determineVariableFromParameter(VariableReference parameter, Type parameterType, Map<TypeVariable<?>, Type> typeMap) { Map<TypeVariable<?>, Type> parameterTypeMap = getParameterType(parameterType, parameter.getType()); logger.info("Resulting map: " + parameterTypeMap); for (TypeVariable<?> typeVar : parameterTypeMap.keySet()) { Type actualType = parameterTypeMap.get(typeVar); if (typeMap.containsKey(typeVar)) { logger.info("Variable is in map: " + typeVar); Type currentType = typeMap.get(typeVar); if (currentType == null || TypeUtils.isAssignable(actualType, currentType)) { typeMap.put(typeVar, actualType); } else { logger.info("Not assignable: " + typeVar + " with bounds " + Arrays.asList(typeVar.getBounds()) + " and current type " + currentType + " from " + actualType); logger.info("" + GenericTypeReflector.isSuperType(currentType, actualType)); logger.info("" + TypeUtils.isAssignable(actualType, typeVar)); } } else { logger.debug("Variable is not in map: " + typeVar); typeMap.put(typeVar, actualType); } } }
@Test public void testGuavaExample() { Type abstractGuavaExampleString = new TypeToken<AbstractGuavaExample<String>>() { }.getType(); Type guavaExample5 = new TypeToken<GuavaExample5<String>>() { }.getType(); GenericClass abstractClass = new GenericClass(abstractGuavaExampleString); GenericClass concreteClass = new GenericClass(guavaExample5); Assert.assertTrue(TypeUtils.isAssignable(concreteClass.getType(), abstractClass.getType())); Assert.assertTrue("Cannot assign "+concreteClass+" to "+abstractClass, abstractClass.isAssignableFrom(concreteClass)); Assert.assertTrue(concreteClass.isAssignableTo(abstractClass)); }
@Test public void testGenericInstantiationMapType() throws ConstructionFailedException { GenericClass genericClass = new GenericClass( com.examples.with.different.packagename.generic.GenericParameterExtendingGenericBounds.class); GenericClass instantiatedClass = genericClass.getGenericInstantiation(); //GenericClass instantiatedClass = linkedlistOfTypeVariable.getGenericInstantiation(listOfInteger.getTypeVariableMap()); System.out.println(instantiatedClass.toString()); Type parameterType = instantiatedClass.getParameterTypes().get(0); Assert.assertTrue(TypeUtils.isAssignable(parameterType, Map.class)); Assert.assertTrue(parameterType instanceof ParameterizedType); ParameterizedType parameterizedType = (ParameterizedType) parameterType; Assert.assertEquals(String.class, parameterizedType.getActualTypeArguments()[0]); }