package com.fasterxml.jackson.databind.util;
import java.util.*;
import com.fasterxml.jackson.core.SerializableString;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
/**
* Helper class used for storing String serializations of
* enumerations.
*/
public final class EnumValues
implements java.io.Serializable
{
private static final long serialVersionUID = 1;
private final Class<Enum<?>> _enumClass;
private final Enum<?>[] _values;
private final SerializableString[] _textual;
private transient EnumMap<?,SerializableString> _asMap;
private EnumValues(Class<Enum<?>> enumClass, SerializableString[] textual)
{
_enumClass = enumClass;
_values = enumClass.getEnumConstants();
_textual = textual;
}
/**
* NOTE: do NOT call this if configuration may change, and choice between toString()
* and name() might change dynamically.
*/
public static EnumValues construct(SerializationConfig config, Class<Enum<?>> enumClass) {
if (config.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)) {
return constructFromToString(config, enumClass);
}
return constructFromName(config, enumClass);
}
public static EnumValues constructFromName(MapperConfig<?> config, Class<Enum<?>> enumClass)
{
// Enum types with per-instance sub-classes need special handling
Class<? extends Enum<?>> enumCls = ClassUtil.findEnumType(enumClass);
Enum<?>[] enumValues = enumCls.getEnumConstants();
if (enumValues == null) {
throw new IllegalArgumentException("Can not determine enum constants for Class "+enumClass.getName());
}
String[] names = config.getAnnotationIntrospector().findEnumValues(enumCls, enumValues, new String[enumValues.length]);
SerializableString[] textual = new SerializableString[enumValues.length];
for (int i = 0, len = enumValues.length; i < len; ++i) {
Enum<?> en = enumValues[i];
String name = names[i];
if (name == null) {
name = en.name();
}
textual[en.ordinal()] = config.compileString(name);
}
return new EnumValues(enumClass, textual);
}
public static EnumValues constructFromToString(MapperConfig<?> config, Class<Enum<?>> enumClass)
{
Class<? extends Enum<?>> cls = ClassUtil.findEnumType(enumClass);
Enum<?>[] values = cls.getEnumConstants();
if (values != null) {
SerializableString[] textual = new SerializableString[values.length];
for (Enum<?> en : values) {
textual[en.ordinal()] = config.compileString(en.toString());
}
return new EnumValues(enumClass, textual);
}
throw new IllegalArgumentException("Can not determine enum constants for Class "+enumClass.getName());
}
public SerializableString serializedValueFor(Enum<?> key) {
return _textual[key.ordinal()];
}
public Collection<SerializableString> values() {
return Arrays.asList(_textual);
}
/**
* Convenience accessor for getting raw Enum instances.
*
* @since 2.6
*/
public List<Enum<?>> enums() {
return Arrays.asList(_values);
}
/**
* Method used for serialization and introspection by core Jackson code.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public EnumMap<?,SerializableString> internalMap() {
EnumMap<?,SerializableString> result = _asMap;
if (result == null) {
// Alas, need to create it in a round-about way, due to typing constraints...
Map<Enum<?>,SerializableString> map = new LinkedHashMap<Enum<?>,SerializableString>();
for (Enum<?> en : _values) {
map.put(en, _textual[en.ordinal()]);
}
result = new EnumMap(map);
}
return result;
}
/**
* @since 2.2
*/
public Class<Enum<?>> getEnumClass() { return _enumClass; }
}