1 package com.fasterxml.jackson.databind.util;
2
3 import java.util.*;
4
5 import com.fasterxml.jackson.core.SerializableString;
6 import com.fasterxml.jackson.databind.*;
7 import com.fasterxml.jackson.databind.cfg.MapperConfig;
8
9
13 public final class EnumValues
14 implements java.io.Serializable
15 {
16 private static final long serialVersionUID = 1;
17
18 private final Class<Enum<?>> _enumClass;
19
20 private final Enum<?>[] _values;
21 private final SerializableString[] _textual;
22
23 private transient EnumMap<?,SerializableString> _asMap;
24
25 private EnumValues(Class<Enum<?>> enumClass, SerializableString[] textual)
26 {
27 _enumClass = enumClass;
28 _values = enumClass.getEnumConstants();
29 _textual = textual;
30 }
31
32
36 public static EnumValues construct(SerializationConfig config, Class<Enum<?>> enumClass) {
37 if (config.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)) {
38 return constructFromToString(config, enumClass);
39 }
40 return constructFromName(config, enumClass);
41 }
42
43 public static EnumValues constructFromName(MapperConfig<?> config, Class<Enum<?>> enumClass)
44 {
45
46 Class<? extends Enum<?>> enumCls = ClassUtil.findEnumType(enumClass);
47 Enum<?>[] enumValues = enumCls.getEnumConstants();
48 if (enumValues == null) {
49 throw new IllegalArgumentException("Cannot determine enum constants for Class "+enumClass.getName());
50 }
51 String[] names = config.getAnnotationIntrospector().findEnumValues(enumCls, enumValues, new String[enumValues.length]);
52 SerializableString[] textual = new SerializableString[enumValues.length];
53 for (int i = 0, len = enumValues.length; i < len; ++i) {
54 Enum<?> en = enumValues[i];
55 String name = names[i];
56 if (name == null) {
57 name = en.name();
58 }
59 textual[en.ordinal()] = config.compileString(name);
60 }
61 return construct(enumClass, textual);
62 }
63
64 public static EnumValues constructFromToString(MapperConfig<?> config, Class<Enum<?>> enumClass)
65 {
66 Class<? extends Enum<?>> cls = ClassUtil.findEnumType(enumClass);
67 Enum<?>[] values = cls.getEnumConstants();
68 if (values == null) {
69 throw new IllegalArgumentException("Cannot determine enum constants for Class "+enumClass.getName());
70 }
71 ArrayList<String> external = new ArrayList<>(values.length);
72 for (Enum<?> en : values) {
73 external.add(en.toString());
74 }
75 return construct(config, enumClass, external);
76 }
77
78
81 public static EnumValues construct(MapperConfig<?> config, Class<Enum<?>> enumClass,
82 List<String> externalValues) {
83 final int len = externalValues.size();
84 SerializableString[] textual = new SerializableString[len];
85 for (int i = 0; i < len; ++i) {
86 textual[i] = config.compileString(externalValues.get(i));
87 }
88 return construct(enumClass, textual);
89 }
90
91
94 public static EnumValues construct(Class<Enum<?>> enumClass,
95 SerializableString[] externalValues) {
96 return new EnumValues(enumClass, externalValues);
97 }
98
99 public SerializableString serializedValueFor(Enum<?> key) {
100 return _textual[key.ordinal()];
101 }
102
103 public Collection<SerializableString> values() {
104 return Arrays.asList(_textual);
105 }
106
107
112 public List<Enum<?>> enums() {
113 return Arrays.asList(_values);
114 }
115
116
119 @SuppressWarnings({ "unchecked", "rawtypes" })
120 public EnumMap<?,SerializableString> internalMap() {
121 EnumMap<?,SerializableString> result = _asMap;
122 if (result == null) {
123
124 Map<Enum<?>,SerializableString> map = new LinkedHashMap<Enum<?>,SerializableString>();
125 for (Enum<?> en : _values) {
126 map.put(en, _textual[en.ordinal()]);
127 }
128 result = new EnumMap(map);
129 }
130 return result;
131 }
132
133
136 public Class<Enum<?>> getEnumClass() { return _enumClass; }
137 }
138