package fr.openwide.core.jpa.config.spring.convert.converter; import java.io.Serializable; import java.util.Collections; import java.util.Set; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.converter.ConditionalGenericConverter; import fr.openwide.core.jpa.business.generic.model.GenericEntity; /** * Converts a GenericEntity to a String. * Only matches if the target GenericEntity key type can be converted to String.class. */ public class GenericEntityToStringSpringConverter implements ConditionalGenericConverter { private final ConversionService conversionService; public GenericEntityToStringSpringConverter(ConversionService conversionService) { this.conversionService = conversionService; } @Override public Set<ConvertiblePair> getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(GenericEntity.class, String.class)); } @Override @SuppressWarnings({ "unchecked", "rawtypes" }) public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { /* * NOTE: for the official javac to infer types properly, the GenericEntity below must be left as a raw type. * Eclipse JDT works fine without this hack. */ return canConvertKey((Class<? extends GenericEntity>) sourceType.getType(), targetType.getType()); } private <K extends Serializable & Comparable<K>, E extends GenericEntity<K, ?>> boolean canConvertKey(Class<E> sourceType, Class<?> targetType) { Class<K> keyType = GenericEntityTypeResolver.resolveKeyTypeParameter(sourceType); if (keyType != null) { return this.conversionService.canConvert(keyType, targetType); } else { return false; } } @Override @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { if (source == null) { return null; } return convertKey((GenericEntity<?, ?>) source, (Class<? extends String>) targetType.getType()); } private <K extends Serializable & Comparable<K>, E extends GenericEntity<K, ?>> String convertKey(E source, Class<? extends String> targetType) { K id = source.getId(); if (id == null) { throw new RuntimeException("The entity id was null"); } else { return conversionService.convert(id, targetType); } } }