fix: 元数据内容丰富化

This commit is contained in:
wangyu 2021-03-21 22:18:26 +08:00
parent 383f0630d3
commit 4b0a346088
3 changed files with 99 additions and 34 deletions

View File

@ -22,6 +22,7 @@ public abstract class Domain implements Po, Serializable {
* 主键
*/
@Id
@Property(readonly = true)
protected String id;
/**

View File

@ -1,13 +1,20 @@
package com.flyfish.framework.beans.meta;
import com.flyfish.framework.annotations.Property;
import com.flyfish.framework.utils.StringFormats;
import lombok.Data;
import lombok.val;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.mongodb.core.mapping.Document;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.stream.Collectors;
@ -41,6 +48,61 @@ public class BeanProperty {
// 类型为object时拥有子表单
private List<BeanProperty> children;
/**
* 来自属性解释器构造
* 支持对象嵌套
*
* @param descriptor 解释器
* @return 结果
*/
public static BeanProperty form(PropertyDescriptor descriptor, Class<?> beanClass) {
BeanProperty property = new BeanProperty();
property.setName(descriptor.getName());
property.setType(BeanPropertyType.of(descriptor, beanClass));
// 尝试获取field
Field field = FieldUtils.getField(beanClass, descriptor.getName(), true);
// 存在field可以干一些坏事
if (null != field) {
Property props = AnnotationUtils.findAnnotation(field, Property.class);
if (null != props) {
String parentName = Optional.ofNullable(beanClass.getAnnotation(RestBean.class)).map(RestBean::name).orElse("");
property.setTitle(props.inherited() ? parentName + props.title() : props.title());
property.setDescription(props.description());
property.setReadonly(props.readonly());
}
}
Class<?> clazz = descriptor.getPropertyType();
switch (property.getType()) {
case LIST:
// 尝试获取泛型参数存在时赋值子表单
if (null != field && field.isAnnotationPresent(SubBean.class)) {
parseSubClass(field).ifPresent(subClazz -> property.setChildren(from(subClazz)));
}
break;
case OBJECT:
// 有子bean注解才处理
if (null != field && field.isAnnotationPresent(SubBean.class)) {
property.setChildren(from(clazz));
}
break;
case DB_REF:
// 当存在db-ref时解析为动态数据源
Document document = AnnotationUtils.findAnnotation(clazz, Document.class);
if (null != document) {
property.prop("uri", document.value());
} else {
property.setType(BeanPropertyType.STRING);
}
break;
case ENUM:
// 为枚举时填入枚举类型
String name = StringFormats.camel2Line(ClassUtils.getShortClassName(clazz));
property.prop("code", name);
break;
}
return property;
}
/**
* 类加载并解析属性
*
@ -56,44 +118,35 @@ public class BeanProperty {
}
/**
* 来自属性解释器构造
* 支持对象嵌套
* 解析子类型用于表格组件
*
* @param descriptor 解释器
* @param field 反射域
* @return 结果
*/
public static BeanProperty form(PropertyDescriptor descriptor, Class<?> beanClass) {
// 尝试获取field
Field field = FieldUtils.getField(beanClass, descriptor.getName(), true);
// 存在field可以干一些坏事
BeanProperty property = new BeanProperty();
property.setName(descriptor.getName());
property.setType(BeanPropertyType.of(descriptor, beanClass));
if (null != field) {
Property props = AnnotationUtils.findAnnotation(field, Property.class);
if (null != props) {
String parentName = Optional.ofNullable(beanClass.getAnnotation(RestBean.class)).map(RestBean::name).orElse("");
property.setTitle(props.inherited() ? parentName + props.title() : props.title());
property.setDescription(props.description());
property.setReadonly(props.readonly());
}
private static Optional<Class<?>> parseSubClass(Field field) {
// 获取实际的泛型
Type type = field.getGenericType();
if (type instanceof ParameterizedType) {
val types = TypeUtils.getTypeArguments((ParameterizedType) type);
return types.entrySet().stream().findFirst().map(entry -> {
Type parsed = entry.getValue();
if (parsed instanceof Class) {
Class<?> clazz = (Class<?>) parsed;
if (!ClassUtils.isPrimitiveOrWrapper(clazz) && !CharSequence.class.isAssignableFrom(clazz)) {
return clazz;
}
}
return null;
});
}
Class<?> clazz = descriptor.getPropertyType();
if (property.getType() == BeanPropertyType.OBJECT) {
// 有子bean注解才处理
if (null != field && field.isAnnotationPresent(SubBean.class)) {
property.setChildren(from(clazz));
}
} else if (property.getType() == BeanPropertyType.DB_REF) {
// 当存在db-ref时解析为动态数据源
RestBean restBean = clazz.getAnnotation(RestBean.class);
if (null != restBean) {
String uri = restBean.value();
Map<String, Object> props = new HashMap<>();
props.put("uri", uri);
property.setProps(props);
}
return Optional.empty();
}
public BeanProperty prop(String key, Object value) {
if (null == props) {
props = new HashMap<>();
}
return property;
props.put(key, value);
return this;
}
}

View File

@ -0,0 +1,11 @@
package com.flyfish.framework.beans.meta;
/**
* 枚举常用的bean属性
* @author wangyu
*/
public interface BeanProps {
// 表格的列支持组件化
String COLUMNS = "columns";
}