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

Commit c877486

Browse files
authored
Merge pull request #761 from linwumingshi/fix/generics-type-name
fix: 🐛 fix the Generics typeName or returnType error
2 parents 694a234 + 0aac955 commit c877486

2 files changed

Lines changed: 69 additions & 20 deletions

File tree

src/main/java/com/ly/doc/helper/JsonBuildHelper.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,8 @@ public static String buildReturnJson(DocJavaMethod docJavaMethod, ProjectDocConf
9292
Map<String, JavaType> actualTypesMap = docJavaMethod.getActualTypesMap();
9393
String returnType = apiReturn.getGenericCanonicalName();
9494
if (Objects.nonNull(actualTypesMap)) {
95-
for (Map.Entry<String, JavaType> entry : actualTypesMap.entrySet()) {
96-
typeName = typeName.replace(entry.getKey(), entry.getValue().getCanonicalName());
97-
returnType = returnType.replace(entry.getKey(), entry.getValue().getCanonicalName());
98-
}
95+
typeName = JavaClassUtil.getGenericsNameByActualTypesMap(typeName, actualTypesMap);
96+
returnType = JavaClassUtil.getGenericsNameByActualTypesMap(returnType, actualTypesMap);
9997
}
10098
if (JavaClassValidateUtil.isPrimitive(typeName)) {
10199
if (DocGlobalConstants.JAVA_STRING_FULLY.equals(typeName)) {

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

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ private static List<DocJavaField> getFields(JavaClass cls1, int counter, Map<Str
157157
List<JavaMethod> javaMethods = cls1.getMethods();
158158
for (JavaMethod method : javaMethods) {
159159
String methodName = method.getName();
160-
if (method.getAnnotations().size() < 1) {
160+
if (method.getAnnotations().isEmpty()) {
161161
continue;
162162
}
163163
int paramSize = method.getParameters().size();
@@ -335,7 +335,7 @@ public static Object getEnumValue(JavaClass javaClass, boolean formDataEnum) {
335335
for (JavaField javaField : javaFields) {
336336
String simpleName = javaField.getType().getSimpleName();
337337
StringBuilder valueBuilder = new StringBuilder();
338-
valueBuilder.append("\"").append(javaField.getName()).append("\"").toString();
338+
valueBuilder.append("\"").append(javaField.getName()).append("\"");
339339
if (formDataEnum) {
340340
value = valueBuilder.toString();
341341
return value;
@@ -360,7 +360,7 @@ public static String getEnumParams(JavaClass javaClass) {
360360
// string comment
361361
String exception = javaField.getInitializationExpression();
362362
// add a separator to Enum values for display better.
363-
if (stringBuilder.length() > 0){
363+
if (stringBuilder.length() > 0) {
364364
stringBuilder.append(", ");
365365
}
366366
stringBuilder.append(javaField.getName());
@@ -544,12 +544,12 @@ public static List<JavaType> getActualTypes(JavaType javaType) {
544544
public static Map<String, JavaType> getActualTypesMap(JavaClass javaClass) {
545545
Map<String, JavaType> genericMap = new HashMap<>(10);
546546
List<JavaTypeVariable<JavaGenericDeclaration>> variables = javaClass.getTypeParameters();
547-
if (variables.size() < 1) {
547+
if (variables.isEmpty()) {
548548
return genericMap;
549549
}
550550
List<JavaType> javaTypes = getActualTypes(javaClass);
551551
for (int i = 0; i < variables.size(); i++) {
552-
if (javaTypes.size() > 0) {
552+
if (!javaTypes.isEmpty()) {
553553
genericMap.put(variables.get(i).getName(), javaTypes.get(i));
554554
}
555555
}
@@ -592,7 +592,7 @@ public static Set<String> getParamGroupJavaClass(JavaAnnotation javaAnnotation)
592592
addGroupClass(annotationValueList, javaClassList);
593593
String simpleAnnotationName = javaAnnotation.getType().getValue();
594594
// add default group
595-
if (javaClassList.size() == 0 && JavaClassValidateUtil.isJSR303Required(simpleAnnotationName)) {
595+
if (javaClassList.isEmpty() && JavaClassValidateUtil.isJSR303Required(simpleAnnotationName)) {
596596
javaClassList.add("javax.validation.groups.Default");
597597
}
598598
return javaClassList;
@@ -602,16 +602,16 @@ public static String getClassTagsValue(final JavaClass cls, final String tagName
602602
if (StringUtil.isNotEmpty(tagName)) {
603603
StringBuilder result = new StringBuilder();
604604
List<DocletTag> tags = cls.getTags();
605-
for (int i = 0; i < tags.size(); i++) {
606-
if (!tagName.equals(tags.get(i).getName())) {
605+
for (DocletTag tag : tags) {
606+
if (!tagName.equals(tag.getName())) {
607607
continue;
608608
}
609-
String value = tags.get(i).getValue();
609+
String value = tag.getValue();
610610
if (StringUtil.isEmpty(value) && checkComments) {
611611
throw new RuntimeException("ERROR: #" + cls.getName()
612612
+ "() - bad @" + tagName + " javadoc from " + cls.getName() + ", must be add comment if you use it.");
613613
}
614-
if (tagName.equals(tags.get(i).getName())) {
614+
if (tagName.equals(tag.getName())) {
615615
if (result.length() > 0) {
616616
result.append(",");
617617
}
@@ -721,15 +721,15 @@ public static void genericParamMap(Map<String, String> genericMap, JavaClass cls
721721
return;
722722
}
723723
List<JavaTypeVariable<JavaGenericDeclaration>> variables = cls.getTypeParameters();
724-
if (variables.size() > 0) {
724+
if (!variables.isEmpty()) {
725725
for (int i = 0; i < cls.getTypeParameters().size() && i < globGicName.length; i++) {
726726
genericMap.put(variables.get(i).getName(), globGicName[i]);
727727
}
728728
return;
729729
}
730730
try {
731-
Class c = Class.forName(cls.getCanonicalName());
732-
TypeVariable[] tValue = c.getTypeParameters();
731+
Class<?> c = Class.forName(cls.getCanonicalName());
732+
TypeVariable<?>[] tValue = c.getTypeParameters();
733733
for (int i = 0; i < tValue.length && i < globGicName.length; i++) {
734734
genericMap.put(tValue[i].getName(), globGicName[i]);
735735
}
@@ -803,8 +803,11 @@ public static Map<String, String> getJsonIgnoresProp(JavaAnnotation annotation,
803803

804804

805805
/**
806-
* @param javaField
807-
* @return
806+
* getFieldGenericType by ClassLoader
807+
*
808+
* @param javaField JavaField
809+
* @param classLoader ClassLoader
810+
* @return fieldGenericType
808811
*/
809812
private static String getFieldGenericType(JavaField javaField, ClassLoader classLoader) {
810813
if (JavaClassValidateUtil.isPrimitive(javaField.getType().getGenericCanonicalName())
@@ -813,7 +816,7 @@ private static String getFieldGenericType(JavaField javaField, ClassLoader class
813816
}
814817
String name = javaField.getName();
815818
try {
816-
Class c;
819+
Class<?> c;
817820
if (Objects.nonNull(classLoader)) {
818821
c = classLoader.loadClass(javaField.getDeclaringClass().getCanonicalName());
819822
} else {
@@ -846,4 +849,52 @@ private static String getReturnGenericType(JavaMethod javaMethod, ClassLoader cl
846849
return null;
847850
}
848851
}
852+
853+
854+
/**
855+
* Replaces generic type parameters in a given type name with their corresponding actual types,
856+
* based on the provided mapping.
857+
*
858+
* @param originalName the original type name containing generic type parameters
859+
* @param actualTypesMap a mapping of generic type parameter names to their corresponding actual types
860+
* @return the type name with generic type parameters replaced by their actual types
861+
*/
862+
public static String getGenericsNameByActualTypesMap(String originalName, Map<String, JavaType> actualTypesMap) {
863+
// Find the index of the last left angle bracket '<' and the first right angle bracket '>'
864+
int typeNameLastLeftIndex = originalName.lastIndexOf('<');
865+
int typeNameFirstRightIndex = originalName.indexOf('>', typeNameLastLeftIndex);
866+
867+
// If both angle brackets are found
868+
if (typeNameLastLeftIndex > 0 && typeNameFirstRightIndex > 0) {
869+
// Extract the substring containing the generics
870+
String genericsString = originalName.substring(typeNameLastLeftIndex + 1, typeNameFirstRightIndex);
871+
String[] generics = genericsString.split(",");
872+
873+
// StringBuilder to build the replaced string
874+
StringBuilder resultString = new StringBuilder();
875+
// Append the portion of originalName before the generics, including the '<'
876+
resultString.append(originalName, 0, typeNameLastLeftIndex + 1);
877+
878+
// Replace each generic type
879+
for (String generic : generics) {
880+
// Trim the generic type to remove leading/trailing whitespaces
881+
String trimmedGeneric = generic.trim();
882+
// Look up the mapped type in the actualTypesMap
883+
JavaType mappedType = actualTypesMap.get(trimmedGeneric);
884+
// If a mapping is found, append the mapped type; otherwise, keep the original generic type
885+
resultString.append(mappedType != null ? mappedType.getCanonicalName() : trimmedGeneric);
886+
// Append a comma after each replaced generic type
887+
resultString.append(",");
888+
}
889+
// Remove the trailing comma
890+
resultString.setLength(resultString.length() - 1);
891+
// Append the portion of originalName after the generics, including the '>'
892+
resultString.append(originalName, typeNameFirstRightIndex, originalName.length());
893+
894+
return resultString.toString();
895+
}
896+
// Return originalName unchanged if no generics are found
897+
return originalName;
898+
}
899+
849900
}

0 commit comments

Comments
 (0)