Last active
May 20, 2016 08:33
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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