Skip to content

Instantly share code, notes, and snippets.

@EsikAntony
Last active May 20, 2016 08:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EsikAntony/610fd35e2b96382b93a22b08b2d751d8 to your computer and use it in GitHub Desktop.
Save EsikAntony/610fd35e2b96382b93a22b08b2d751d8 to your computer and use it in GitHub Desktop.
Dozer enum coverter, which respect JAXB generated enums with value() and fromValue() methods
package ru.aesik.dozer.converter;
import org.dozer.DozerConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;
import javax.xml.bind.annotation.XmlEnum;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Честный конвертер перечислений, поддерживающий перечисления, сгенерированные JAXB
*
* @author AEsik
* Date: 20.05.2016
*/
public class EnumDozerConverter extends DozerConverter<Enum, String> {
private static final Logger LOG = LoggerFactory.getLogger(EnumDozerConverter.class);
private static final Map<Class, Converter> ENUM_CONVERTER_CACHE = new ConcurrentHashMap<>();
public EnumDozerConverter() {
super(Enum.class, String.class);
}
@Override
public String convertTo(Enum source, String destination) {
return getConverter(source).convertTo(source, destination);
}
@Override
public Enum convertFrom(String source, Enum destination) {
return getConverter(destination).convertFrom(source, destination);
}
private Converter getConverter(Enum enumValue) {
Converter converter = ENUM_CONVERTER_CACHE.get(enumValue.getDeclaringClass());
if (converter == null) {
LOG.debug("Cache missing for [{}] enum", enumValue.getDeclaringClass().getName());
// в соответсвии с JAXB должны быть три атрибута у генерированного перечисления:
// аннотация XmlEnum, метод получения (value) и установки значения (fromValue)
Annotation annotation = enumValue.getDeclaringClass().getAnnotation(XmlEnum.class);
Method value = ReflectionUtils.findMethod(enumValue.getDeclaringClass(), "value");
Method fromValue = ReflectionUtils.findMethod(enumValue.getDeclaringClass(), "fromValue", String.class);
if (annotation != null
&& value != null
&& fromValue != null) {
LOG.debug("Constructing JAXB enum converter for [{}] enum", enumValue.getDeclaringClass().getName());
converter = new Converter() {
@Override
public String convertTo(Enum source, String destination) {
return String.valueOf(ReflectionUtils.invokeMethod(value, source, null));
}
@Override
public Enum convertFrom(String source, Enum destination) {
return (Enum) ReflectionUtils.invokeMethod(fromValue, destination, source);
}
};
} else {
LOG.debug("Constructing simple enum converter for [{}] enum", enumValue.getDeclaringClass().getName());
converter = new Converter() {
@Override
public String convertTo(Enum source, String destination) {
return source.toString();
}
@Override
public Enum convertFrom(String source, Enum destination) {
return Enum.valueOf(destination.getDeclaringClass(), source);
}
};
}
ENUM_CONVERTER_CACHE.put(enumValue.getDeclaringClass(), converter);
}
return converter;
}
private interface Converter {
String convertTo(Enum source, String destination);
Enum convertFrom(String source, Enum destination);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment