Skip to content
This repository was archived by the owner on Dec 4, 2025. It is now read-only.

Commit 8629038

Browse files
committed
feat(enum): ✨ Support @JsonValue annotation on enum fields
1 parent 8b52b96 commit 8629038

1 file changed

Lines changed: 93 additions & 28 deletions

File tree

src/main/java/com/ly/doc/utils/JavaClassUtil.java

Lines changed: 93 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,10 @@ public static String getSameSignatureMethodCommonFromInterface(JavaClass cls, Ja
308308

309309
/**
310310
* Get the value of an enum
311-
*
311+
* <p>
312312
* This method retrieves the value of an enum based on its fields or methods. It
313313
* supports loading the enum class via reflection and determines the enum value based
314-
* on the presence of specific annotations such as JsonValue and JsonCreator.
314+
* on the presence of specific annotations such as {@code JsonValue}
315315
* @param javaClass The JavaClass object representing the enum class
316316
* @param builder A ProjectDocConfigBuilder object used to retrieve API configuration
317317
* and the class loader
@@ -325,37 +325,102 @@ public static Object getEnumValue(JavaClass javaClass, ProjectDocConfigBuilder b
325325
if (Objects.isNull(javaFields)) {
326326
throw new RuntimeException(javaClass.getName() + " enum not existed");
327327
}
328-
List<JavaMethod> methodList = javaClass.getMethods();
329-
String methodName = null;
330-
for (JavaMethod method : methodList) {
331-
List<JavaAnnotation> annotations = method.getAnnotations();
332-
for (JavaAnnotation annotation : annotations) {
333-
String annotationName = annotation.getType().getValue();
334-
// enum serialize while use JsonValue and JsonCreator annotation
335-
if (DocAnnotationConstants.JSON_VALUE.equals(annotationName)
336-
|| DocAnnotationConstants.JSON_CREATOR.equals(annotationName)) {
337-
methodName = method.getName();
338-
break;
339-
}
328+
329+
// Try getting value from method with JsonValue annotation
330+
String methodName = findMethodWithJsonValue(javaClass);
331+
if (Objects.nonNull(methodName) && !formDataEnum) {
332+
Class<?> enumClass = loadEnumClass(javaClass, builder);
333+
if (Objects.nonNull(enumClass)) {
334+
return EnumUtil.getFieldValueByMethod(enumClass, methodName);
340335
}
336+
return null;
341337
}
342-
if (Objects.nonNull(methodName) && !formDataEnum) {
343-
ApiConfig apiConfig = builder.getApiConfig();
344-
ClassLoader classLoader = apiConfig.getClassLoader();
345-
Class<?> enumClass = null;
346-
try {
347-
if (Objects.nonNull(classLoader)) {
348-
enumClass = classLoader.loadClass(javaClass.getFullyQualifiedName());
349-
}
350-
else {
351-
enumClass = Class.forName(javaClass.getFullyQualifiedName());
352-
}
338+
339+
// Try getting value from field with JsonValue annotation
340+
Optional<JavaField> fieldWithJsonValue = findFieldWithJsonValue(javaClass);
341+
if (fieldWithJsonValue.isPresent()) {
342+
Class<?> enumClass = loadEnumClass(javaClass, builder);
343+
if (Objects.nonNull(enumClass)) {
344+
return EnumUtil.getFieldValue(enumClass, fieldWithJsonValue.get().getName());
345+
}
346+
return null;
347+
}
348+
349+
// Default handling for enum values
350+
return processDefaultEnumFields(javaFields, formDataEnum);
351+
}
352+
353+
/**
354+
* Loads the enum class using the specified class loader from the builder.
355+
* @param javaClass The JavaClass representing the enum
356+
* @param builder The configuration builder
357+
* @return The loaded Class object for the enum
358+
*/
359+
private static Class<?> loadEnumClass(JavaClass javaClass, ProjectDocConfigBuilder builder) {
360+
ApiConfig apiConfig = builder.getApiConfig();
361+
ClassLoader classLoader = apiConfig.getClassLoader();
362+
try {
363+
if (Objects.nonNull(classLoader)) {
364+
return classLoader.loadClass(javaClass.getFullyQualifiedName());
353365
}
354-
catch (ClassNotFoundException e) {
355-
e.printStackTrace();
366+
else {
367+
return Class.forName(javaClass.getFullyQualifiedName());
356368
}
357-
return EnumUtil.getFieldValueByMethod(enumClass, methodName);
358369
}
370+
catch (ClassNotFoundException e) {
371+
e.printStackTrace();
372+
return null;
373+
}
374+
}
375+
376+
/**
377+
* Finds the method in the class that has {@code JsonValue} annotation.
378+
* @param javaClass The JavaClass to search in
379+
* @return The method name if found, null otherwise
380+
*/
381+
private static String findMethodWithJsonValue(JavaClass javaClass) {
382+
for (JavaMethod method : javaClass.getMethods()) {
383+
for (JavaAnnotation annotation : method.getAnnotations()) {
384+
String annotationName = annotation.getType().getValue();
385+
// Handle JsonValue annotation
386+
if (DocAnnotationConstants.JSON_VALUE.equals(annotationName)) {
387+
AnnotationValue property = annotation.getProperty(DocAnnotationConstants.VALUE_PROP);
388+
// If property is null or its value is true, return the method name
389+
if (property == null || Objects.equals(property.getParameterValue(), true)) {
390+
return method.getName();
391+
}
392+
}
393+
}
394+
}
395+
return null;
396+
}
397+
398+
/**
399+
* Finds the field in the class that has {@code JsonValue} annotation.
400+
* @param javaClass The JavaClass to search in
401+
* @return An Optional containing the field if found
402+
*/
403+
private static Optional<JavaField> findFieldWithJsonValue(JavaClass javaClass) {
404+
return javaClass.getFields()
405+
.stream()
406+
.filter(field -> field.getAnnotations().stream().anyMatch(javaAnnotation -> {
407+
if (DocAnnotationConstants.JSON_VALUE.equals(javaAnnotation.getType().getValue())) {
408+
// Check if the property is null, if so, consider it as "true"
409+
AnnotationValue property = javaAnnotation.getProperty(DocAnnotationConstants.VALUE_PROP);
410+
return property == null || Objects.equals(property.getParameterValue(), true);
411+
}
412+
return false;
413+
}))
414+
.findFirst();
415+
}
416+
417+
/**
418+
* Handles the default logic for processing enum fields.
419+
* @param javaFields The list of JavaField objects representing enum fields
420+
* @param formDataEnum A boolean indicating if the enum is a form data enum
421+
* @return The value based on the enum field processing logic
422+
*/
423+
private static Object processDefaultEnumFields(List<JavaField> javaFields, boolean formDataEnum) {
359424
Object value = null;
360425
int index = 0;
361426
for (JavaField javaField : javaFields) {

0 commit comments

Comments
 (0)