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

Commit 2a15d8b

Browse files
authored
Merge pull request #935 from linwumingshi/fix/constant
fix: 🐛 resolve incorrect parsing of constants in `@JsonProperty` and `@JSONField` annotation
2 parents 13b8e04 + cd81eaf commit 2a15d8b

5 files changed

Lines changed: 150 additions & 39 deletions

File tree

src/main/java/com/ly/doc/handler/IWebSocketRequestHandler.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
*/
2121
package com.ly.doc.handler;
2222

23+
import com.ly.doc.builder.ProjectDocConfigBuilder;
2324
import com.ly.doc.constants.DocAnnotationConstants;
2425
import com.ly.doc.constants.DocTags;
2526
import com.ly.doc.model.request.ServerEndpoint;
@@ -28,6 +29,7 @@
2829
import com.thoughtworks.qdox.model.JavaAnnotation;
2930
import com.thoughtworks.qdox.model.JavaClass;
3031

32+
import java.util.List;
3133
import java.util.Objects;
3234
import java.util.Optional;
3335

@@ -40,11 +42,13 @@ public interface IWebSocketRequestHandler {
4042

4143
/**
4244
* handle class annotation `@ServerEndpoint`
45+
* @param projectBuilder the project configuration builder
4346
* @param javaAnnotation javaAnnotation @ServerEndpoint
4447
* @param cls JavaClass
4548
* @return ServerEndpoint
4649
*/
47-
default ServerEndpoint handleServerEndpoint(JavaClass cls, JavaAnnotation javaAnnotation) {
50+
default ServerEndpoint handleServerEndpoint(ProjectDocConfigBuilder projectBuilder, JavaClass cls,
51+
JavaAnnotation javaAnnotation) {
4852
if (Objects.nonNull(cls.getTagByName(DocTags.IGNORE))) {
4953
return null;
5054
}
@@ -56,7 +60,9 @@ default ServerEndpoint handleServerEndpoint(JavaClass cls, JavaAnnotation javaAn
5660
.ifPresent(builder::setUrl);
5761

5862
// get subProtocols of annotation
59-
builder.setSubProtocols(JavaClassUtil.getAnnotationValueStrings(javaAnnotation, "subprotocols"));
63+
List<String> subProtocols = JavaClassUtil.getAnnotationValueStrings(projectBuilder, javaAnnotation,
64+
"subprotocols");
65+
builder.setSubProtocols(subProtocols);
6066

6167
// Handle 'decoders' property
6268
builder.setDecoders(JavaClassUtil.getAnnotationValueClassNames(javaAnnotation, "decoders"));

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,20 @@ protected static FieldJsonAnnotationInfo getFieldJsonAnnotationInfo(ProjectDocCo
176176
// Handle @JSONField
177177
if (DocAnnotationConstants.SHORT_JSON_FIELD.equals(annotationName)) {
178178
if (null != annotation.getProperty(DocAnnotationConstants.NAME_PROP)) {
179-
fieldJsonAnnotationInfo.setFieldName(StringUtil
180-
.removeQuotes(annotation.getProperty(DocAnnotationConstants.NAME_PROP).toString()));
179+
AnnotationValue annotationValue = annotation.getProperty(DocAnnotationConstants.NAME_PROP);
180+
String fieldName = DocUtil.resolveAnnotationValue(projectBuilder.getApiConfig().getClassLoader(),
181+
annotationValue);
182+
fieldJsonAnnotationInfo.setFieldName(fieldName);
181183
}
182184
}
183185

184186
// Handle @JsonProperty
185187
else if (DocAnnotationConstants.SHORT_JSON_PROPERTY.equals(annotationName)
186188
|| DocAnnotationConstants.GSON_ALIAS_NAME.equals(annotationName)) {
187189
AnnotationValue annotationValue = annotation.getProperty(DocAnnotationConstants.VALUE_PROP);
188-
if (null != annotationValue) {
189-
fieldJsonAnnotationInfo.setFieldName(StringUtil.removeQuotes(annotationValue.toString()));
190-
}
190+
String fieldName = DocUtil.resolveAnnotationValue(projectBuilder.getApiConfig().getClassLoader(),
191+
annotationValue);
192+
fieldJsonAnnotationInfo.setFieldName(fieldName);
191193
}
192194
// Handle JSR303 required
193195
if (JavaClassValidateUtil.isJSR303Required(annotationName) && !isResp) {

src/main/java/com/ly/doc/template/IWebSocketTemplate.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,25 @@
3939
import com.ly.doc.utils.JavaClassUtil;
4040
import com.power.common.util.StringUtil;
4141
import com.power.common.util.ValidateUtil;
42-
import com.thoughtworks.qdox.model.*;
42+
import com.thoughtworks.qdox.model.JavaAnnotation;
43+
import com.thoughtworks.qdox.model.JavaClass;
44+
import com.thoughtworks.qdox.model.JavaMethod;
45+
import com.thoughtworks.qdox.model.JavaParameter;
46+
import com.thoughtworks.qdox.model.JavaType;
4347
import com.thoughtworks.qdox.model.impl.DefaultJavaParameterizedType;
4448

45-
import java.util.*;
49+
import java.util.ArrayList;
50+
import java.util.Collection;
51+
import java.util.Collections;
52+
import java.util.Comparator;
53+
import java.util.HashMap;
54+
import java.util.HashSet;
55+
import java.util.LinkedHashSet;
56+
import java.util.List;
57+
import java.util.Map;
58+
import java.util.Objects;
59+
import java.util.Optional;
60+
import java.util.Set;
4661
import java.util.concurrent.atomic.AtomicInteger;
4762
import java.util.logging.Logger;
4863
import java.util.regex.Matcher;
@@ -157,7 +172,7 @@ default WebSocketDoc buildEntryPointWebSocketDoc(final JavaClass javaClass, Proj
157172

158173
webSocketRequestHandler = Objects.isNull(webSocketRequestHandler) ? DefaultWebSocketRequestHandler.getInstance()
159174
: webSocketRequestHandler;
160-
ServerEndpoint serverEndpoint = webSocketRequestHandler.handleServerEndpoint(javaClass,
175+
ServerEndpoint serverEndpoint = webSocketRequestHandler.handleServerEndpoint(projectBuilder, javaClass,
161176
serverEndpointAnnotation);
162177

163178
WebSocketDoc webSocketDoc = new WebSocketDoc();

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

Lines changed: 79 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,78 @@
2020
*/
2121
package com.ly.doc.utils;
2222

23-
import com.ly.doc.constants.*;
23+
import com.ly.doc.constants.DocAnnotationConstants;
24+
import com.ly.doc.constants.DocGlobalConstants;
25+
import com.ly.doc.constants.DocTags;
26+
import com.ly.doc.constants.JAXRSAnnotations;
27+
import com.ly.doc.constants.JakartaJaxrsAnnotations;
28+
import com.ly.doc.constants.JavaTypeConstants;
29+
import com.ly.doc.constants.MediaType;
2430
import com.ly.doc.extension.dict.DictionaryValuesResolver;
25-
import com.ly.doc.model.*;
31+
import com.ly.doc.model.ApiConfig;
32+
import com.ly.doc.model.ApiDataDictionary;
33+
import com.ly.doc.model.ApiDocDict;
34+
import com.ly.doc.model.ApiErrorCode;
35+
import com.ly.doc.model.ApiErrorCodeDictionary;
36+
import com.ly.doc.model.ApiReqParam;
37+
import com.ly.doc.model.DataDict;
38+
import com.ly.doc.model.DocJavaField;
39+
import com.ly.doc.model.FormData;
40+
import com.ly.doc.model.SystemPlaceholders;
2641
import com.ly.doc.model.request.RequestMapping;
2742
import com.mifmif.common.regex.Generex;
28-
import com.power.common.util.*;
43+
import com.power.common.util.CollectionUtil;
44+
import com.power.common.util.DateTimeUtil;
45+
import com.power.common.util.EnumUtil;
46+
import com.power.common.util.IDCardUtil;
47+
import com.power.common.util.RandomUtil;
48+
import com.power.common.util.StringUtil;
2949
import com.thoughtworks.qdox.JavaProjectBuilder;
30-
import com.thoughtworks.qdox.model.*;
50+
import com.thoughtworks.qdox.model.DocletTag;
51+
import com.thoughtworks.qdox.model.JavaAnnotation;
52+
import com.thoughtworks.qdox.model.JavaClass;
53+
import com.thoughtworks.qdox.model.JavaField;
54+
import com.thoughtworks.qdox.model.JavaMember;
55+
import com.thoughtworks.qdox.model.JavaMethod;
3156
import com.thoughtworks.qdox.model.expression.Add;
3257
import com.thoughtworks.qdox.model.expression.AnnotationValue;
58+
import com.thoughtworks.qdox.model.expression.Constant;
3359
import com.thoughtworks.qdox.model.expression.Expression;
3460
import com.thoughtworks.qdox.model.expression.FieldRef;
3561
import net.datafaker.Faker;
3662
import org.apache.commons.codec.digest.DigestUtils;
3763
import org.apache.commons.lang3.StringUtils;
3864

3965
import java.text.DecimalFormat;
40-
import java.time.*;
66+
import java.time.Instant;
67+
import java.time.LocalDate;
68+
import java.time.LocalDateTime;
69+
import java.time.LocalTime;
70+
import java.time.MonthDay;
71+
import java.time.OffsetDateTime;
72+
import java.time.Year;
73+
import java.time.YearMonth;
74+
import java.time.ZoneId;
4175
import java.time.format.DateTimeFormatter;
42-
import java.util.*;
76+
import java.util.ArrayList;
77+
import java.util.Arrays;
78+
import java.util.Collections;
79+
import java.util.Date;
80+
import java.util.HashMap;
81+
import java.util.HashSet;
82+
import java.util.IdentityHashMap;
83+
import java.util.Iterator;
84+
import java.util.LinkedHashMap;
85+
import java.util.LinkedHashSet;
86+
import java.util.List;
87+
import java.util.Locale;
88+
import java.util.Map;
89+
import java.util.Objects;
90+
import java.util.Optional;
91+
import java.util.Set;
92+
import java.util.Stack;
93+
import java.util.TimeZone;
94+
import java.util.UUID;
4395
import java.util.logging.Logger;
4496
import java.util.regex.Pattern;
4597
import java.util.stream.Collectors;
@@ -969,30 +1021,36 @@ public static String getPathUrl(ClassLoader classLoader, JavaAnnotation annotati
9691021
* @return annotation value
9701022
*/
9711023
public static String resolveAnnotationValue(ClassLoader classLoader, AnnotationValue annotationValue) {
1024+
// if it is a constant, return its value directly
1025+
if (annotationValue instanceof Constant) {
1026+
return ((Constant) annotationValue).getValue().toString();
1027+
}
1028+
// if it is an add operation, return the result directly
9721029
if (annotationValue instanceof Add) {
9731030
Add add = (Add) annotationValue;
9741031
String leftValue = resolveAnnotationValue(classLoader, add.getLeft());
9751032
String rightValue = resolveAnnotationValue(classLoader, add.getRight());
9761033
return StringUtil.removeQuotes(leftValue + rightValue);
9771034
}
978-
else {
979-
if (annotationValue instanceof FieldRef) {
980-
FieldRef fieldRef = (FieldRef) annotationValue;
981-
JavaField javaField = fieldRef.getField();
982-
if (javaField != null) {
983-
String fieldValue = JavaFieldUtil.getConstantsFieldValue(classLoader, javaField.getDeclaringClass(),
984-
javaField.getName());
985-
if (StringUtil.isNotEmpty(fieldValue)) {
986-
return StringUtil.removeQuotes(fieldValue);
987-
}
988-
return StringUtil.removeQuotes(javaField.getInitializationExpression());
1035+
// if it is a field reference, return its value directly
1036+
if (annotationValue instanceof FieldRef) {
1037+
FieldRef fieldRef = (FieldRef) annotationValue;
1038+
JavaField javaField = fieldRef.getField();
1039+
if (javaField != null) {
1040+
String fieldValue = JavaFieldUtil.getConstantsFieldValue(classLoader, javaField.getDeclaringClass(),
1041+
javaField.getName());
1042+
if (StringUtil.isNotEmpty(fieldValue)) {
1043+
return StringUtil.removeQuotes(fieldValue);
9891044
}
1045+
return StringUtil.removeQuotes(javaField.getInitializationExpression());
9901046
}
991-
return Optional.ofNullable(annotationValue)
992-
.map(Expression::getParameterValue)
993-
.map(Object::toString)
994-
.orElse(StringUtil.EMPTY);
9951047
}
1048+
// default return
1049+
return Optional.ofNullable(annotationValue)
1050+
.map(Expression::getParameterValue)
1051+
.map(Object::toString)
1052+
.orElse(StringUtil.EMPTY);
1053+
9961054
}
9971055

9981056
/**

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

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,13 @@
2323
package com.ly.doc.utils;
2424

2525
import com.ly.doc.builder.ProjectDocConfigBuilder;
26-
import com.ly.doc.constants.*;
26+
import com.ly.doc.constants.DefaultClassConstants;
27+
import com.ly.doc.constants.DocAnnotationConstants;
28+
import com.ly.doc.constants.DocGlobalConstants;
29+
import com.ly.doc.constants.DocTags;
30+
import com.ly.doc.constants.DocValidatorAnnotationEnum;
31+
import com.ly.doc.constants.JSRAnnotationConstants;
32+
import com.ly.doc.constants.JavaTypeConstants;
2733
import com.ly.doc.model.ApiConfig;
2834
import com.ly.doc.model.ApiDataDictionary;
2935
import com.ly.doc.model.DocJavaField;
@@ -34,7 +40,15 @@
3440
import com.power.common.util.EnumUtil;
3541
import com.power.common.util.StringUtil;
3642
import com.thoughtworks.qdox.JavaProjectBuilder;
37-
import com.thoughtworks.qdox.model.*;
43+
import com.thoughtworks.qdox.model.DocletTag;
44+
import com.thoughtworks.qdox.model.JavaAnnotation;
45+
import com.thoughtworks.qdox.model.JavaClass;
46+
import com.thoughtworks.qdox.model.JavaField;
47+
import com.thoughtworks.qdox.model.JavaGenericDeclaration;
48+
import com.thoughtworks.qdox.model.JavaMethod;
49+
import com.thoughtworks.qdox.model.JavaParameterizedType;
50+
import com.thoughtworks.qdox.model.JavaType;
51+
import com.thoughtworks.qdox.model.JavaTypeVariable;
3852
import com.thoughtworks.qdox.model.expression.AnnotationValue;
3953
import com.thoughtworks.qdox.model.expression.AnnotationValueList;
4054
import com.thoughtworks.qdox.model.expression.Constant;
@@ -43,8 +57,22 @@
4357
import com.thoughtworks.qdox.model.impl.DefaultJavaParameterizedType;
4458
import org.apache.commons.lang3.StringUtils;
4559

46-
import java.lang.reflect.*;
47-
import java.util.*;
60+
import java.lang.reflect.Field;
61+
import java.lang.reflect.Method;
62+
import java.lang.reflect.Modifier;
63+
import java.lang.reflect.Type;
64+
import java.lang.reflect.TypeVariable;
65+
import java.util.ArrayList;
66+
import java.util.Collection;
67+
import java.util.Collections;
68+
import java.util.HashMap;
69+
import java.util.HashSet;
70+
import java.util.LinkedList;
71+
import java.util.List;
72+
import java.util.Map;
73+
import java.util.Objects;
74+
import java.util.Optional;
75+
import java.util.Set;
4876
import java.util.logging.Logger;
4977
import java.util.stream.Collectors;
5078

@@ -1323,11 +1351,13 @@ public static List<String> getAnnotationValueClassNames(JavaAnnotation javaAnnot
13231351
* annotation. It handles both single string values and lists of string values. If the
13241352
* property is not found or has no valid string values, an empty list is returned.
13251353
* </p>
1354+
* @param projectBuilder the project configuration builder
13261355
* @param javaAnnotation the annotation containing the property
13271356
* @param propertyName the name of the property to retrieve
13281357
* @return a list of string values or an empty list if not present
13291358
*/
1330-
public static List<String> getAnnotationValueStrings(JavaAnnotation javaAnnotation, String propertyName) {
1359+
public static List<String> getAnnotationValueStrings(ProjectDocConfigBuilder projectBuilder,
1360+
JavaAnnotation javaAnnotation, String propertyName) {
13311361
AnnotationValue propertyValue = javaAnnotation.getProperty(propertyName);
13321362
if (propertyValue != null) {
13331363
if (propertyValue instanceof AnnotationValueList) {
@@ -1338,9 +1368,9 @@ public static List<String> getAnnotationValueStrings(JavaAnnotation javaAnnotati
13381368
.filter(StringUtil::isNotEmpty)
13391369
.collect(Collectors.toList());
13401370
}
1341-
if (propertyValue instanceof Constant) {
1342-
return Collections.singletonList(((Constant) propertyValue).getValue().toString());
1343-
}
1371+
String value = DocUtil.resolveAnnotationValue(projectBuilder.getApiConfig().getClassLoader(),
1372+
propertyValue);
1373+
return Collections.singletonList(value);
13441374
}
13451375
return Collections.emptyList();
13461376
}

0 commit comments

Comments
 (0)