/** * Returns a converter that can convert an IntermediateRepresentation from the given {@code sourceType} to the * given {@code targetType} using a chain formed with given {@code candidates}. The returned converter * uses some (or all) of the given {@code candidates} as delegates. * * @param sourceType The source type of the converter * @param targetType The target type of the converter * @param candidates The candidates to form a chain with * @param <S> The source type of the converter * @param <T> The target type of the converter * @return A converter for the given source and target types * * @throws CannotConvertBetweenTypesException * if no converter can be created using given candidates */ public static <S, T> ChainedConverter<S, T> calculateChain(Class<S> sourceType, Class<T> targetType, Collection<ContentTypeConverter<?, ?>> candidates) { Route route = calculateRoute(sourceType, targetType, candidates); if (route == null) { throw new CannotConvertBetweenTypesException(format("Cannot build a converter to convert from %s to %s", sourceType.getName(), targetType.getName())); } return new ChainedConverter<>(route.asList()); }
@Override @SuppressWarnings("unchecked") public <T> T convert(Object original, Class<?> sourceType, Class<T> targetType) { if (sourceType.equals(targetType)) { return (T) original; } for (ContentTypeConverter converter : converters) { if (canConvert(converter, sourceType, targetType)) { return (T) converter.convert(original); } } ChainedConverter converter = ChainedConverter.calculateChain(sourceType, targetType, converters); converters.add(0, converter); return (T) converter.convert(original); }
@Override public boolean canConvert(Class<?> sourceType, Class<?> targetType) { if (sourceType.equals(targetType)) { return true; } for (ContentTypeConverter converter : converters) { if (canConvert(converter, sourceType, targetType)) { return true; } } return ChainedConverter.canConvert(sourceType, targetType, converters); }
/** * Indicates whether this converter is capable of converting the given {@code sourceContentType} into * {@code targetContentType}, using the given {@code converters}. When {@code true}, it may use any * number of the given {@code converters} to form a chain. * * @param sourceContentType The content type of the source object * @param targetContentType The content type of the target object * @param converters The converters eligible for use * @param <S> The content type of the source object * @param <T> The content type of the target object * @return {@code true} if this Converter can convert between the given types, using the given converters. * Otherwise {@code false}. */ public static <S, T> boolean canConvert(Class<S> sourceContentType, Class<T> targetContentType, List<ContentTypeConverter<?, ?>> converters) { return calculateRoute(sourceContentType, targetContentType, converters) != null; }
/** * Creates a new instance that uses the given {@code delegates} to form a chain of converters. Note that the * {@code delegates} must for a Continuous chain, meaning that each item must produce an * IntermediateRepresentation of a type that can be consumed by the next delegate. * <p/> * To automatically calculate a route between converters, see {@link #calculateChain(Class source, Class target, * java.util.Collection candidates) calculateChain(source, target, candidates)} * * @param delegates the chain of delegates to perform the conversion */ @SuppressWarnings({"unchecked", "ConstantConditions"}) public ChainedConverter(List<ContentTypeConverter<?,?>> delegates) { Assert.isTrue(delegates != null && !delegates.isEmpty(), () -> "The given delegates may not be null or empty"); Assert.isTrue(isContinuous(delegates), () -> "The given delegates must form a continuous chain"); this.delegates = new ArrayList<>(delegates); target = (Class<T>) this.delegates.get(this.delegates.size() - 1).targetType(); source = (Class<S>) delegates.get(0).expectedSourceType(); }
private static <S, T> Route calculateRoute(Class<S> sourceType, Class<T> targetType, Collection<ContentTypeConverter<?, ?>> candidates) { return new RouteCalculator(candidates).calculateRoute(sourceType, targetType); }
/** * Creates a new instance that uses the given {@code delegates} to form a chain of converters. Note that the * {@code delegates} must for a Continuous chain, meaning that each item must produce an * IntermediateRepresentation of a type that can be consumed by the next delegate. * <p/> * To automatically calculate a route between converters, see {@link #calculateChain(Class source, Class target, * java.util.Collection candidates) calculateChain(source, target, candidates)} * * @param delegates the chain of delegates to perform the conversion */ @SuppressWarnings({"unchecked", "ConstantConditions"}) public ChainedConverter(List<ContentTypeConverter<?,?>> delegates) { Assert.isTrue(delegates != null && !delegates.isEmpty(), () -> "The given delegates may not be null or empty"); Assert.isTrue(isContinuous(delegates), () -> "The given delegates must form a continuous chain"); this.delegates = new ArrayList<>(delegates); target = (Class<T>) this.delegates.get(this.delegates.size() - 1).targetType(); source = (Class<S>) delegates.get(0).expectedSourceType(); }
@Override @SuppressWarnings("unchecked") public <T> T convert(Object original, Class<?> sourceType, Class<T> targetType) { if (sourceType.equals(targetType)) { return (T) original; } for (ContentTypeConverter converter : converters) { if (canConvert(converter, sourceType, targetType)) { return (T) converter.convert(original); } } ChainedConverter converter = ChainedConverter.calculateChain(sourceType, targetType, converters); converters.add(0, converter); return (T) converter.convert(original); }
/** * Returns a converter that can convert an IntermediateRepresentation from the given {@code sourceType} to the * given {@code targetType} using a chain formed with given {@code candidates}. The returned converter * uses some (or all) of the given {@code candidates} as delegates. * * @param sourceType The source type of the converter * @param targetType The target type of the converter * @param candidates The candidates to form a chain with * @param <S> The source type of the converter * @param <T> The target type of the converter * @return A converter for the given source and target types * * @throws CannotConvertBetweenTypesException * if no converter can be created using given candidates */ public static <S, T> ChainedConverter<S, T> calculateChain(Class<S> sourceType, Class<T> targetType, Collection<ContentTypeConverter<?, ?>> candidates) { Route route = calculateRoute(sourceType, targetType, candidates); if (route == null) { throw new CannotConvertBetweenTypesException(format("Cannot build a converter to convert from %s to %s", sourceType.getName(), targetType.getName())); } return new ChainedConverter<>(route.asList()); }
/** * Indicates whether this converter is capable of converting the given {@code sourceContentType} into * {@code targetContentType}, using the given {@code converters}. When {@code true}, it may use any * number of the given {@code converters} to form a chain. * * @param sourceContentType The content type of the source object * @param targetContentType The content type of the target object * @param converters The converters eligible for use * @param <S> The content type of the source object * @param <T> The content type of the target object * @return {@code true} if this Converter can convert between the given types, using the given converters. * Otherwise {@code false}. */ public static <S, T> boolean canConvert(Class<S> sourceContentType, Class<T> targetContentType, List<ContentTypeConverter<?, ?>> converters) { return calculateRoute(sourceContentType, targetContentType, converters) != null; }
@Override public boolean canConvert(Class<?> sourceType, Class<?> targetType) { if (sourceType.equals(targetType)) { return true; } for (ContentTypeConverter converter : converters) { if (canConvert(converter, sourceType, targetType)) { return true; } } return ChainedConverter.canConvert(sourceType, targetType, converters); }
/** * Creates a new instance that uses the given {@code delegates} to form a chain of converters. Note that the * {@code delegates} must for a Continuous chain, meaning that each item must produce an * IntermediateRepresentation of a type that can be consumed by the next delegate. * <p/> * To automatically calculate a route between converters, see {@link #calculateChain(Class source, Class target, * java.util.Collection candidates) calculateChain(source, target, candidates)} * * @param delegates the chain of delegates to perform the conversion */ @SuppressWarnings({"unchecked", "ConstantConditions"}) public ChainedConverter(List<ContentTypeConverter<?,?>> delegates) { Assert.isTrue(delegates != null && !delegates.isEmpty(), () -> "The given delegates may not be null or empty"); Assert.isTrue(isContinuous(delegates), () -> "The given delegates must form a continuous chain"); this.delegates = new ArrayList<>(delegates); target = (Class<T>) this.delegates.get(this.delegates.size() - 1).targetType(); source = (Class<S>) delegates.get(0).expectedSourceType(); }
@Override @SuppressWarnings("unchecked") public <T> T convert(Object original, Class<?> sourceType, Class<T> targetType) { if (sourceType.equals(targetType)) { return (T) original; } for (ContentTypeConverter converter : converters) { if (canConvert(converter, sourceType, targetType)) { return (T) converter.convert(original); } } ChainedConverter converter = ChainedConverter.calculateChain(sourceType, targetType, converters); converters.add(0, converter); return (T) converter.convert(original); }
/** * Returns a converter that can convert an IntermediateRepresentation from the given {@code sourceType} to the * given {@code targetType} using a chain formed with given {@code candidates}. The returned converter * uses some (or all) of the given {@code candidates} as delegates. * * @param sourceType The source type of the converter * @param targetType The target type of the converter * @param candidates The candidates to form a chain with * @param <S> The source type of the converter * @param <T> The target type of the converter * @return A converter for the given source and target types * * @throws CannotConvertBetweenTypesException * if no converter can be created using given candidates */ public static <S, T> ChainedConverter<S, T> calculateChain(Class<S> sourceType, Class<T> targetType, Collection<ContentTypeConverter<?, ?>> candidates) { Route route = calculateRoute(sourceType, targetType, candidates); if (route == null) { throw new CannotConvertBetweenTypesException(format("Cannot build a converter to convert from %s to %s", sourceType.getName(), targetType.getName())); } return new ChainedConverter<>(route.asList()); }
/** * Indicates whether this converter is capable of converting the given {@code sourceContentType} into * {@code targetContentType}, using the given {@code converters}. When {@code true}, it may use any * number of the given {@code converters} to form a chain. * * @param sourceContentType The content type of the source object * @param targetContentType The content type of the target object * @param converters The converters eligible for use * @param <S> The content type of the source object * @param <T> The content type of the target object * @return {@code true} if this Converter can convert between the given types, using the given converters. * Otherwise {@code false}. */ public static <S, T> boolean canConvert(Class<S> sourceContentType, Class<T> targetContentType, List<ContentTypeConverter<?, ?>> converters) { return calculateRoute(sourceContentType, targetContentType, converters) != null; }
@Override public boolean canConvert(Class<?> sourceType, Class<?> targetType) { if (sourceType.equals(targetType)) { return true; } for (ContentTypeConverter converter : converters) { if (canConvert(converter, sourceType, targetType)) { return true; } } return ChainedConverter.canConvert(sourceType, targetType, converters); }
private static <S, T> Route calculateRoute(Class<S> sourceType, Class<T> targetType, Collection<ContentTypeConverter<?, ?>> candidates) { return new RouteCalculator(candidates).calculateRoute(sourceType, targetType); }
private static <S, T> Route calculateRoute(Class<S> sourceType, Class<T> targetType, Collection<ContentTypeConverter<?, ?>> candidates) { return new RouteCalculator(candidates).calculateRoute(sourceType, targetType); }