Skip to content

Commit 24ba192

Browse files
processing JsonProperty annotation used on enum
1 parent f71a044 commit 24ba192

File tree

3 files changed

+130
-31
lines changed

3 files changed

+130
-31
lines changed

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/TsType.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,9 @@ public UnionType(List<? extends TsType> types) {
155155

156156
@Override
157157
public String format(Settings settings) {
158-
return Utils.join(format(types, settings), " | ");
158+
return types.isEmpty()
159+
? "never"
160+
: Utils.join(format(types, settings), " | ");
159161
}
160162

161163
}

typescript-generator-core/src/main/java/cz/habarta/typescript/generator/parser/Jackson2Parser.java

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
package cz.habarta.typescript.generator.parser;
33

44
import com.fasterxml.jackson.annotation.JsonFormat;
5+
import com.fasterxml.jackson.annotation.JsonProperty;
56
import com.fasterxml.jackson.annotation.JsonSubTypes;
67
import com.fasterxml.jackson.annotation.JsonTypeInfo;
78
import com.fasterxml.jackson.annotation.JsonTypeName;
@@ -255,46 +256,79 @@ protected EnumModel<?> parseEnum(SourceType<Class<?>> sourceClass) {
255256
jsonFormat.shape() == JsonFormat.Shape.NUMBER ||
256257
jsonFormat.shape() == JsonFormat.Shape.NUMBER_FLOAT ||
257258
jsonFormat.shape() == JsonFormat.Shape.NUMBER_INT);
259+
260+
final List<EnumMemberModel<String>> stringMembers = new ArrayList<>();
261+
final List<EnumMemberModel<Number>> numberMembers = new ArrayList<>();
262+
if (sourceClass.type.isEnum()) {
263+
final Class<?> enumClass = (Class<?>) sourceClass.type;
264+
265+
try {
266+
Method valueMethod = null;
267+
final BeanInfo beanInfo = Introspector.getBeanInfo(enumClass);
268+
for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
269+
final Method readMethod = propertyDescriptor.getReadMethod();
270+
if (readMethod.isAnnotationPresent(JsonValue.class)) {
271+
valueMethod = readMethod;
272+
}
273+
}
274+
275+
int index = 0;
276+
for (Field field : enumClass.getFields()) {
277+
if (field.isEnumConstant()) {
278+
if (isNumberBased) {
279+
final Number value = getNumberEnumValue(field, valueMethod, index++);
280+
numberMembers.add(new EnumMemberModel<>(field.getName(), value, null));
281+
} else {
282+
final String value = getStringEnumValue(field, valueMethod);
283+
stringMembers.add(new EnumMemberModel<>(field.getName(), value, null));
284+
}
285+
}
286+
}
287+
} catch (Exception e) {
288+
System.out.println(String.format("Cannot get enum values for '%s' enum", enumClass.getName()));
289+
e.printStackTrace(System.out);
290+
}
291+
}
292+
258293
if (isNumberBased) {
259-
return parseNumberEnum(sourceClass);
294+
return new EnumModel<>(sourceClass.type, EnumKind.NumberBased, numberMembers, null);
260295
} else {
261-
return super.parseEnum(sourceClass);
296+
return new EnumModel<>(sourceClass.type, EnumKind.StringBased, stringMembers, null);
262297
}
263298
}
264299

265-
private EnumModel<Number> parseNumberEnum(SourceType<Class<?>> sourceClass) {
266-
final Class<?> enumClass = sourceClass.type;
267-
final List<EnumMemberModel<Number>> members = new ArrayList<>();
268-
269-
try {
270-
Method valueMethod = null;
271-
final BeanInfo beanInfo = Introspector.getBeanInfo(enumClass);
272-
for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors()) {
273-
final Method readMethod = propertyDescriptor.getReadMethod();
274-
if (readMethod.isAnnotationPresent(JsonValue.class)) {
275-
valueMethod = readMethod;
276-
}
300+
private Number getNumberEnumValue(Field field, Method valueMethod, int index) throws Exception {
301+
if (valueMethod != null) {
302+
final Object valueObject = invokeJsonValueMethod(field, valueMethod);
303+
if (valueObject instanceof Number) {
304+
return (Number) valueObject;
277305
}
306+
}
307+
return index;
308+
}
278309

279-
int index = 0;
280-
for (Field field : enumClass.getFields()) {
281-
if (field.isEnumConstant()) {
282-
final Number value;
283-
if (valueMethod != null) {
284-
final Object constant = field.get(null);
285-
value = (Number) valueMethod.invoke(constant);
286-
} else {
287-
value = index++;
288-
}
289-
members.add(new EnumMemberModel<>(field.getName(), value, null));
290-
}
310+
private String getStringEnumValue(Field field, Method valueMethod) throws Exception {
311+
if (valueMethod != null) {
312+
final Object valueObject = invokeJsonValueMethod(field, valueMethod);
313+
if (valueObject instanceof String) {
314+
return (String) valueObject;
291315
}
292-
} catch (Exception e) {
293-
System.out.println(String.format("Cannot get enum values for '%s' enum", enumClass.getName()));
294-
e.printStackTrace(System.out);
295316
}
317+
if (field.isAnnotationPresent(JsonProperty.class)) {
318+
final JsonProperty jsonProperty = field.getAnnotation(JsonProperty.class);
319+
if (!jsonProperty.value().equals(JsonProperty.USE_DEFAULT_NAME)) {
320+
return jsonProperty.value();
321+
}
322+
}
323+
return field.getName();
324+
}
296325

297-
return new EnumModel<>(enumClass, EnumKind.NumberBased, members, null);
326+
private Object invokeJsonValueMethod(Field field, Method valueMethod) throws ReflectiveOperationException {
327+
field.setAccessible(true);
328+
final Object constant = field.get(null);
329+
valueMethod.setAccessible(true);
330+
final Object valueObject = valueMethod.invoke(constant);
331+
return valueObject;
298332
}
299333

300334
}

typescript-generator-core/src/test/java/cz/habarta/typescript/generator/EnumTest.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11

22
package cz.habarta.typescript.generator;
33

4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import com.fasterxml.jackson.annotation.JsonValue;
46
import static org.junit.Assert.*;
57
import org.junit.Test;
68

@@ -69,6 +71,39 @@ public void testEnumAsNumberBasedEnum() {
6971
assertEquals(expected, output);
7072
}
7173

74+
@Test
75+
public void testEnumWithJsonPropertyAnnotations() {
76+
final Settings settings = TestUtils.settings();
77+
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(SideWithJsonPropertyAnnotations.class));
78+
final String expected = (
79+
"\n" +
80+
"type SideWithJsonPropertyAnnotations = 'left-side' | 'right-side';\n"
81+
).replace("'", "\"");
82+
assertEquals(expected, output);
83+
}
84+
85+
@Test
86+
public void testEnumWithJsonValueAnnotation() {
87+
final Settings settings = TestUtils.settings();
88+
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(SideWithJsonValueAnnotations.class));
89+
final String expected = (
90+
"\n" +
91+
"type SideWithJsonValueAnnotations = 'left-side' | 'right-side';\n"
92+
).replace("'", "\"");
93+
assertEquals(expected, output);
94+
}
95+
96+
@Test
97+
public void testEmptyEnum() {
98+
final Settings settings = TestUtils.settings();
99+
final String output = new TypeScriptGenerator(settings).generateTypeScript(Input.from(EmptyEnum.class));
100+
final String expected = (
101+
"\n" +
102+
"type EmptyEnum = never;\n"
103+
).replace("'", "\"");
104+
assertEquals(expected, output);
105+
}
106+
72107
private static class AClass {
73108
public Direction direction;
74109
}
@@ -80,4 +115,32 @@ enum Direction {
80115
West
81116
}
82117

118+
enum SideWithJsonPropertyAnnotations {
119+
@JsonProperty("left-side")
120+
Left,
121+
@JsonProperty("right-side")
122+
Right
123+
}
124+
125+
enum SideWithJsonValueAnnotations {
126+
@JsonProperty("@JsonProperty ignored since @JsonValue has higher precedence")
127+
Left("left-side"),
128+
@JsonProperty("@JsonProperty ignored since @JsonValue has higher precedence")
129+
Right("right-side");
130+
131+
private final String jsonValue;
132+
133+
private SideWithJsonValueAnnotations(String jsonValue) {
134+
this.jsonValue = jsonValue;
135+
}
136+
137+
@JsonValue
138+
public Object getJsonValue() {
139+
return jsonValue;
140+
}
141+
}
142+
143+
enum EmptyEnum {
144+
}
145+
83146
}

0 commit comments

Comments
 (0)