package org.transgalactica.management.rest.converter; import java.io.IOException; import java.util.LinkedHashMap; import java.util.Map; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotWritableException; import org.transgalactica.fwk.web.converter.DelegateHttpMessageConverter; public class HeaderTypeHttpMessageConverter<T> extends DelegateHttpMessageConverter<T> { private static final String HEADER_KEY = "TransGalactica-Content-Type"; /** Mappings from header value to types */ private final Map<String, Class<? extends T>> headersMapping = new LinkedHashMap<>(); public HeaderTypeHttpMessageConverter(HttpMessageConverter<T> delegate) { super(delegate); } @Override public void write(T t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { String headerValue = findHeaderMapping(t.getClass()); if (headerValue != null) { outputMessage.getHeaders().add(HEADER_KEY, headerValue); } super.write(t, contentType, outputMessage); } @Override public T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { String headerType = inputMessage.getHeaders().getFirst(HEADER_KEY); Class<? extends T> target = findHeaderMapping(headerType); if (target != null) { return super.read(target, inputMessage); } return super.read(clazz, inputMessage); } public HeaderTypeHttpMessageConverter<T> addMapping(String value, Class<? extends T> type) { headersMapping.put(value, type); return this; } protected Class<? extends T> findHeaderMapping(String key) { return headersMapping.get(key); } protected String findHeaderMapping(Class<?> clazz) { for (Map.Entry<String, Class<? extends T>> entry : headersMapping.entrySet()) { if (entry.getValue().isAssignableFrom(clazz)) { return entry.getKey(); } } return null; } }