diff --git a/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanController.java b/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanController.java index 8f6ec59..c529852 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanController.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanController.java @@ -3,14 +3,14 @@ package com.flyfish.framework.beans.meta; import com.flyfish.framework.bean.Result; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ClassUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.Arrays; +import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; /** * bean控制器,可以通过类直接返回bean信息 @@ -29,10 +29,11 @@ public class BeanController { */ @GetMapping("") public Result> beanInfo(String className) { + if (StringUtils.isBlank(className)) { + return Result.ok(Collections.emptyList()); + } try { - return Result.ok(Arrays.stream(BeanUtils.getPropertyDescriptors(ClassUtils.getClass(className))) - .map(BeanProperty::form) - .collect(Collectors.toList())); + return Result.ok(BeanProperty.from(BeanUtils.getPropertyDescriptors(ClassUtils.getClass(className)))); } catch (ClassNotFoundException e) { log.error(e.getMessage(), e); return Result.error(e.getMessage()); diff --git a/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanProperty.java b/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanProperty.java index 31ddcff..165b082 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanProperty.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanProperty.java @@ -1,11 +1,14 @@ package com.flyfish.framework.beans.meta; +import com.flyfish.framework.beans.annotations.RestBean; import lombok.Data; import org.springframework.beans.BeanUtils; import java.beans.PropertyDescriptor; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; /** @@ -23,9 +26,24 @@ public class BeanProperty { // bean属性的类型,js类型 private BeanPropertyType type; + // 属性 + private Map props; + // 类型为object时,拥有子表单 private List children; + /** + * 类加载并解析属性 + * + * @return 结果 + */ + public static List from(PropertyDescriptor[] descriptors) { + return Arrays.stream(descriptors) + .filter(descriptor -> !"class".equals(descriptor.getName())) + .map(BeanProperty::form) + .collect(Collectors.toList()); + } + /** * 来自属性解释器构造 * 支持对象嵌套 @@ -34,14 +52,23 @@ public class BeanProperty { * @return 结果 */ public static BeanProperty form(PropertyDescriptor descriptor) { + Class clazz = descriptor.getPropertyType(); BeanProperty property = new BeanProperty(); property.setName(descriptor.getName()); - property.setType(BeanPropertyType.of(descriptor.getPropertyType())); + property.setType(BeanPropertyType.of(descriptor)); if (property.getType() == BeanPropertyType.OBJECT) { - List children = Arrays.stream(BeanUtils.getPropertyDescriptors(descriptor.getPropertyType())) - .map(BeanProperty::form) - .collect(Collectors.toList()); - property.setChildren(children); + // 有子bean注解才处理 + if (clazz.isAnnotationPresent(SubBean.class)) { + List children = from(BeanUtils.getPropertyDescriptors(clazz)); + property.setChildren(children); + } + } else if (property.getType() == BeanPropertyType.DB_REF) { + // 当存在db-ref时,解析为动态数据源 + RestBean restBean = clazz.getAnnotation(RestBean.class); + String uri = restBean.value(); + Map props = new HashMap<>(); + props.put("uri", uri); + property.setProps(props); } return property; } diff --git a/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanPropertyType.java b/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanPropertyType.java index 1ca226d..bce0e39 100644 --- a/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanPropertyType.java +++ b/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/BeanPropertyType.java @@ -1,11 +1,15 @@ package com.flyfish.framework.beans.meta; +import com.flyfish.framework.beans.annotations.RestBean; +import com.flyfish.framework.domain.base.Domain; import lombok.Getter; +import java.beans.PropertyDescriptor; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.List; +import java.util.function.Predicate; /** * bean属性的类型 @@ -22,20 +26,34 @@ public enum BeanPropertyType { DATE("Date", Date.class), ENUM("Enum", Enum.class), LIST("Array", Collection.class), + DB_REF("Ref", descriptor -> { + Class clazz = descriptor.getPropertyType(); + return Domain.class.isAssignableFrom(clazz) && clazz.isAnnotationPresent(RestBean.class); + }), OBJECT("Object", Object.class); - BeanPropertyType(String name, Class ...classes) { + private final Predicate acceptor; + + BeanPropertyType(String name, Class... classes) { this.name = name; this.classes = Arrays.asList(classes); + this.acceptor = null; } private final String name; private final List> classes; - public static BeanPropertyType of(Class clazz) { + BeanPropertyType(String name, Predicate predicate) { + this.name = name; + this.classes = null; + this.acceptor = predicate; + } + + public static BeanPropertyType of(PropertyDescriptor descriptor) { for (BeanPropertyType type : values()) { - if (type.classes.stream().anyMatch(item -> item.isAssignableFrom(clazz))) { + if (null != type.classes && type.classes.stream().anyMatch(item -> item.isAssignableFrom(descriptor.getPropertyType())) || + null != type.acceptor && type.acceptor.test(descriptor)) { return type; } } diff --git a/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/SubBean.java b/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/SubBean.java new file mode 100644 index 0000000..32d01f1 --- /dev/null +++ b/flyfish-web/src/main/java/com/flyfish/framework/beans/meta/SubBean.java @@ -0,0 +1,13 @@ +package com.flyfish.framework.beans.meta; + +import java.lang.annotation.*; + +/** + * 标记需要解析的子bean + * @author wangyu + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface SubBean { +}