Skip to content

Commit 4c6b386

Browse files
committed
feat:支持解析自定义对象
1 parent 5d6c8f0 commit 4c6b386

14 files changed

Lines changed: 582 additions & 118 deletions

File tree

src/main/java/org/github/azirzsk/fcp/entity/PropertyEntity.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
import lombok.Data;
55
import lombok.experimental.Accessors;
66

7+
import java.lang.reflect.Field;
78
import java.lang.reflect.Parameter;
89
import java.util.List;
10+
import java.util.Map;
911

1012
/**
1113
* 函数中,参数的信息
@@ -23,18 +25,42 @@ public class PropertyEntity {
2325
@JSONField(ordinal = 2)
2426
private String description;
2527

28+
/**
29+
* 嵌套的属性
30+
* 当且仅当type为object时,才会有值
31+
*/
32+
@JSONField(ordinal = 3)
33+
private Map<String, PropertyEntity> properties;
34+
2635
@JSONField(name = "enum", ordinal = 3)
2736
private List<Object> enumList;
2837

38+
/**
39+
* 内嵌对应的必填的字段
40+
* 上一层级为object类型时,不为空
41+
*/
42+
@JSONField(ordinal = 4)
43+
private List<String> required;
44+
2945
@JSONField(serialize = false)
30-
private boolean required;
46+
private boolean require;
3147

3248
@JSONField(serialize = false)
3349
private String name;
3450

3551
@JSONField(serialize = false)
3652
private Integer index;
3753

54+
/**
55+
* 对象实际对应的参数
56+
*/
3857
@JSONField(serialize = false)
3958
private Parameter parameter;
59+
60+
/**
61+
* 对象实际对应的字段
62+
* 上一层级为object类型时,不为空
63+
*/
64+
@JSONField(serialize = false)
65+
private Field field;
4066
}

src/main/java/org/github/azirzsk/fcp/parser/ParameterParser.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import lombok.extern.slf4j.Slf4j;
44
import org.github.azirzsk.fcp.entity.ParametersEntity;
55
import org.github.azirzsk.fcp.entity.PropertyEntity;
6+
import org.github.azirzsk.fcp.parser.property.PropertyParser;
67

78
import java.lang.reflect.Parameter;
89
import java.util.*;
@@ -30,7 +31,7 @@ public ParametersEntity parse(Parameter[] parameters) {
3031
}
3132
property.setIndex(i);
3233
properties.put(property.getName(), property);
33-
if (property.isRequired()) {
34+
if (property.isRequire()) {
3435
requiredList.add(property.getName());
3536
}
3637
}

src/main/java/org/github/azirzsk/fcp/parser/PropertyParser.java

Lines changed: 0 additions & 93 deletions
This file was deleted.

src/main/java/org/github/azirzsk/fcp/parser/property/FieldParser.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
import lombok.extern.slf4j.Slf4j;
44
import org.github.azirzsk.fcp.annotation.Property;
55
import org.github.azirzsk.fcp.entity.PropertyEntity;
6+
import org.github.azirzsk.fcp.enums.PropertyType;
67
import org.github.azirzsk.fcp.parser.Parser;
78
import org.github.azirzsk.fcp.utils.ParserUtils;
89

910
import java.lang.reflect.Field;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.Map;
1014

1115
/**
1216
* 根据属性上的{@link Property}注解,解析字段信息
@@ -17,23 +21,25 @@
1721
@Slf4j
1822
public class FieldParser implements Parser<Field, PropertyEntity> {
1923

24+
private static final ObjectPropertyParser OBJECT_PROPERTY_PARSER = new ObjectPropertyParser();
25+
2026
@Override
2127
public PropertyEntity parse(Field field) {
2228
if (log.isDebugEnabled()) {
2329
log.debug("解析字段:{}", field);
2430
}
2531
Property property = field.getAnnotation(Property.class);
2632
if (property == null) {
27-
if (log.isTraceEnabled()) {
28-
log.trace("字段没有@Property注解,不进行解析:{}", field);
33+
if (log.isDebugEnabled()) {
34+
log.debug("字段没有@Property注解,不进行解析:{}", field);
2935
}
3036
return null;
3137
}
3238
PropertyEntity propertyEntity = new PropertyEntity()
3339
.setName(Property.USE_PARAM_NAME.equals(property.name()) ? field.getName() : property.name())
3440
.setDescription(property.desc())
3541
.setField(field)
36-
.setRequired(property.required());
42+
.setRequire(property.required());
3743

3844
// 解析参数对应类型
3945
Class<?> type = property.type();
@@ -42,11 +48,28 @@ public PropertyEntity parse(Field field) {
4248
} else {
4349
propertyEntity.setType(type.getSimpleName().toLowerCase());
4450
}
45-
51+
// object类型的property
52+
if (PropertyType.OBJECT.getName().equals(propertyEntity.getType())) {
53+
Map<String, PropertyEntity> innerProperties = OBJECT_PROPERTY_PARSER.parse(field.getType());
54+
propertyEntity.setProperties(innerProperties);
55+
// require
56+
List<String> innerRequiredList = new ArrayList<>();
57+
for (PropertyEntity innerProperty : innerProperties.values()) {
58+
if (innerProperty.isRequire()) {
59+
innerRequiredList.add(innerProperty.getName());
60+
}
61+
}
62+
propertyEntity.setRequired(innerRequiredList);
63+
}
4664
// 解析参数枚举值
4765
if (property.enums() != Property.NoneConverter.class) {
4866
propertyEntity.setEnumList(ParserUtils.parseEnum(property.enums()));
4967
}
68+
// 参数合法性校验 type:object和枚举值不能同时存在
69+
if (PropertyType.OBJECT.getName().equals(propertyEntity.getType()) && propertyEntity.getEnumList() != null) {
70+
log.warn("参数类型为object时,不能同时设置枚举值。innerProperties:{},enumList:{}", propertyEntity.getProperties(), propertyEntity.getEnumList());
71+
throw new IllegalArgumentException("参数类型为object时,不能同时设置枚举值");
72+
}
5073
if (log.isDebugEnabled()) {
5174
log.debug("字段解析完成");
5275
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package org.github.azirzsk.fcp.parser.property;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.github.azirzsk.fcp.entity.PropertyEntity;
5+
import org.github.azirzsk.fcp.parser.Parser;
6+
7+
import java.lang.reflect.Field;
8+
import java.util.Collections;
9+
import java.util.HashMap;
10+
import java.util.Map;
11+
12+
/**
13+
* @author zhangshukun
14+
* @since 2024/12/26
15+
*/
16+
@Slf4j
17+
public class ObjectPropertyParser implements Parser<Class<?>, Map<String, PropertyEntity>> {
18+
19+
private static final FieldParser FIELD_PARSER = new FieldParser();
20+
21+
@Override
22+
public Map<String, PropertyEntity> parse(Class<?> clazz) {
23+
if (log.isDebugEnabled()) {
24+
log.debug("开始解析类中的属性:{}", clazz);
25+
}
26+
Field[] fields = clazz.getDeclaredFields();
27+
if (fields.length == 0) {
28+
if (log.isDebugEnabled()) {
29+
log.debug("类中没有字段,不进行解析:{}", clazz);
30+
}
31+
return Collections.emptyMap();
32+
}
33+
Map<String, PropertyEntity> res = new HashMap<>();
34+
for (Field field : fields) {
35+
PropertyEntity propertyEntity = FIELD_PARSER.parse(field);
36+
if (propertyEntity == null) {
37+
continue;
38+
}
39+
res.put(propertyEntity.getName(), propertyEntity);
40+
}
41+
if (log.isDebugEnabled()) {
42+
log.debug("类解析完成:{}", clazz);
43+
}
44+
return res;
45+
}
46+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package org.github.azirzsk.fcp.parser.property;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.github.azirzsk.fcp.annotation.Property;
5+
import org.github.azirzsk.fcp.entity.PropertyEntity;
6+
import org.github.azirzsk.fcp.enums.PropertyType;
7+
import org.github.azirzsk.fcp.parser.Parser;
8+
import org.github.azirzsk.fcp.utils.ParserUtils;
9+
10+
import java.lang.reflect.Parameter;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.Map;
14+
15+
/**
16+
* @author zhangshukun
17+
* @since 2024/11/17
18+
*/
19+
@Slf4j
20+
public class PropertyParser implements Parser<Parameter, PropertyEntity> {
21+
22+
private static final ObjectPropertyParser OBJECT_PROPERTY_PARSER = new ObjectPropertyParser();
23+
24+
/**
25+
* 解析参数属性
26+
*
27+
* @param parameter 方法的参数
28+
* @return Function中参数需要的属性
29+
*/
30+
public PropertyEntity parse(Parameter parameter) {
31+
if (log.isTraceEnabled()) {
32+
log.trace("解析参数:{}", parameter);
33+
}
34+
Property property = parameter.getAnnotation(Property.class);
35+
if (property == null) {
36+
if (log.isTraceEnabled()) {
37+
log.trace("参数没有@Property注解,不进行解析:{}", parameter);
38+
}
39+
return null;
40+
}
41+
PropertyEntity propertyEntity = new PropertyEntity()
42+
.setName(Property.USE_PARAM_NAME.equals(property.name()) ? parameter.getName() : property.name())
43+
.setDescription(property.desc())
44+
.setParameter(parameter)
45+
.setRequire(property.required());
46+
47+
// 解析参数对应类型
48+
Class<?> type = property.type();
49+
if (Property.AutoType.class == type) {
50+
propertyEntity.setType(ParserUtils.parseType(parameter.getType()));
51+
} else {
52+
propertyEntity.setType(type.getSimpleName().toLowerCase());
53+
}
54+
// object类型的property
55+
if (PropertyType.OBJECT.getName().equals(propertyEntity.getType())) {
56+
Map<String, PropertyEntity> innerProperties = OBJECT_PROPERTY_PARSER.parse(parameter.getType());
57+
propertyEntity.setProperties(innerProperties);
58+
// require
59+
List<String> innerRequiredList = new ArrayList<>();
60+
for (PropertyEntity innerProperty : innerProperties.values()) {
61+
if (innerProperty.isRequire()) {
62+
innerRequiredList.add(innerProperty.getName());
63+
}
64+
}
65+
propertyEntity.setRequired(innerRequiredList);
66+
}
67+
// 解析参数枚举值
68+
if (property.enums() != Property.NoneConverter.class) {
69+
propertyEntity.setEnumList(ParserUtils.parseEnum(property.enums()));
70+
}
71+
// 参数合法性校验 type:object和枚举值不能同时存在
72+
if (PropertyType.OBJECT.getName().equals(propertyEntity.getType()) && propertyEntity.getEnumList() != null) {
73+
log.warn("参数类型为object时,不能同时设置枚举值。typeClass:{},enumList:{}", type, propertyEntity.getEnumList());
74+
throw new IllegalArgumentException("参数类型为object时,不能同时设置枚举值");
75+
}
76+
if (log.isTraceEnabled()) {
77+
log.trace("解析参数完成");
78+
}
79+
return propertyEntity;
80+
}
81+
82+
}

0 commit comments

Comments
 (0)