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 @Id
@Property(readonly = true)
protected String id; protected String id;
/** /**

View File

@ -1,13 +1,20 @@
package com.flyfish.framework.beans.meta; package com.flyfish.framework.beans.meta;
import com.flyfish.framework.annotations.Property; import com.flyfish.framework.annotations.Property;
import com.flyfish.framework.utils.StringFormats;
import lombok.Data; 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.FieldUtils;
import org.apache.commons.lang3.reflect.TypeUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.mongodb.core.mapping.Document;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -41,6 +48,61 @@ public class BeanProperty {
// 类型为object时拥有子表单 // 类型为object时拥有子表单
private List<BeanProperty> children; 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 结果 * @return 结果
*/ */
public static BeanProperty form(PropertyDescriptor descriptor, Class<?> beanClass) { private static Optional<Class<?>> parseSubClass(Field field) {
// 尝试获取field // 获取实际的泛型
Field field = FieldUtils.getField(beanClass, descriptor.getName(), true); Type type = field.getGenericType();
// 存在field可以干一些坏事 if (type instanceof ParameterizedType) {
BeanProperty property = new BeanProperty(); val types = TypeUtils.getTypeArguments((ParameterizedType) type);
property.setName(descriptor.getName()); return types.entrySet().stream().findFirst().map(entry -> {
property.setType(BeanPropertyType.of(descriptor, beanClass)); Type parsed = entry.getValue();
if (null != field) { if (parsed instanceof Class) {
Property props = AnnotationUtils.findAnnotation(field, Property.class); Class<?> clazz = (Class<?>) parsed;
if (null != props) { if (!ClassUtils.isPrimitiveOrWrapper(clazz) && !CharSequence.class.isAssignableFrom(clazz)) {
String parentName = Optional.ofNullable(beanClass.getAnnotation(RestBean.class)).map(RestBean::name).orElse(""); return clazz;
property.setTitle(props.inherited() ? parentName + props.title() : props.title());
property.setDescription(props.description());
property.setReadonly(props.readonly());
} }
} }
Class<?> clazz = descriptor.getPropertyType(); return null;
if (property.getType() == BeanPropertyType.OBJECT) { });
// 有子bean注解才处理
if (null != field && field.isAnnotationPresent(SubBean.class)) {
property.setChildren(from(clazz));
} }
} else if (property.getType() == BeanPropertyType.DB_REF) { return Optional.empty();
// 当存在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);
} }
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";
}