Search in sources :

Example 1 with ApiDataType

use of com.terran4j.commons.api2doc.domain.ApiDataType in project commons by terran4j.

the class Api2DocObjectFactory method createBean.

/**
 * 如果是 JavaBean 类,就创建这个 JavaBean 对象;<br>
 * 如果是 List / Array 对象,则什么都不做;<br>
 * 如果是 简单类型 对象,就创建符合这个类型的值。
 *
 * @param clazz 数据对象的类型。
 * @return 填充后的数据对象。
 */
private static <T> T createBean(Class<T> clazz, String defaultValue, Stack<Class<?>> classStack) {
    if (clazz == null) {
        return null;
    }
    final ApiDataType dataType = ApiDataType.toDataType(clazz);
    if (dataType == null) {
        log.warn("无法识别的类型, class = {}", clazz);
        return null;
    }
    if (dataType.isArrayType()) {
        if (log.isInfoEnabled()) {
            log.info("数组类型,createBean 不处理, class = {}", clazz);
        }
        return null;
    }
    if (dataType.isSimpleType()) {
        if (defaultValue == null) {
            defaultValue = dataType.getDefault();
        }
        Object result = dataType.parseValue(defaultValue);
        result = adaptSimpleType(result, clazz);
        return (T) result;
    }
    // 处理 JavaBean 对象的情况。
    if (dataType.isObjectType()) {
        T object = null;
        try {
            object = clazz.newInstance();
        } catch (InstantiationException e) {
            log.warn("不能根据类创建对象,class = {}, 原因:{}", clazz, e.getMessage());
            return null;
        } catch (IllegalAccessException e) {
            log.warn("不能根据类创建对象,class = {}, 原因:{}", clazz, e.getMessage());
            return null;
        }
        if (object == null) {
            log.warn("不能根据类创建对象,class = {}", clazz);
            return null;
        }
        // 获取 JavaBean 的属性。
        PropertyDescriptor[] props = PropertyUtils.getPropertyDescriptors(clazz);
        if (props == null || props.length == 0) {
            // 没有属性就不用处理。
            return object;
        }
        // 之前有过此类的信息,不用再次输出。
        if (classStack.contains(clazz)) {
            return object;
        }
        // 有属性,设置属性值。
        classStack.push(clazz);
        for (PropertyDescriptor prop : props) {
            String fieldName = prop.getName();
            try {
                fillField(fieldName, object, classStack);
            } catch (Exception e) {
                log.warn("给字段设值出错, class = {}, fieldName = {}", clazz, fieldName);
            }
        }
        classStack.pop();
        return object;
    }
    log.warn("无法识别的类型,class = {}", clazz);
    return null;
}
Also used : PropertyDescriptor(java.beans.PropertyDescriptor) ApiDataType(com.terran4j.commons.api2doc.domain.ApiDataType)

Example 2 with ApiDataType

use of com.terran4j.commons.api2doc.domain.ApiDataType in project commons by terran4j.

the class Api2DocObjectFactory method fillField.

private static void fillField(String name, Object bean, Stack<Class<?>> classStack) {
    Class<?> clazz = Classes.getTargetClass(bean);
    PropertyDescriptor fieldProp = null;
    try {
        fieldProp = PropertyUtils.getPropertyDescriptor(bean, name);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    } catch (InvocationTargetException e) {
        throw new RuntimeException(e);
    } catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
    }
    if (fieldProp == null) {
        throw new RuntimeException("field[" + name + "] NOT found in class: " + clazz);
    }
    if (Api2DocUtils.isFilter(fieldProp, clazz)) {
        return;
    }
    ApiComment classApiComment = clazz.getAnnotation(ApiComment.class);
    Class<?> defaultSeeClass = ApiCommentUtils.getDefaultSeeClass(classApiComment, null);
    String fieldName = fieldProp.getName();
    Method getMethod = fieldProp.getReadMethod();
    if (getMethod == null) {
        log.warn("没有 getter 方法, class = {}, fieldName = {}", clazz, fieldName);
        return;
    }
    Method setMethod = fieldProp.getWriteMethod();
    if (setMethod == null) {
        log.warn("没有 setter 方法, class = {}, fieldName = {}", clazz, fieldName);
        return;
    }
    Class<?> fieldClass = getMethod.getReturnType();
    Field field = Classes.getField(fieldName, clazz);
    if (field == null) {
        log.warn("找不到字段定义, class = {}, fieldName = {}", clazz, fieldName);
        return;
    }
    ApiDataType fieldDataType = ApiDataType.toDataType(fieldClass);
    if (fieldDataType == null) {
        log.warn("未知字段类型");
        return;
    }
    Object fieldValue = null;
    if (fieldDataType.isSimpleType()) {
        ApiComment apiComment = field.getAnnotation(ApiComment.class);
        String defaultValue = ApiCommentUtils.getSample(apiComment, defaultSeeClass, fieldName);
        fieldValue = createBean(fieldClass, defaultValue, classStack);
        Class<?> paramType = setMethod.getParameterTypes()[0];
        fieldValue = adaptSimpleType(fieldValue, paramType);
    } else if (fieldDataType.isObjectType()) {
        fieldValue = createBean(fieldClass, null, classStack);
    } else if (fieldDataType.isArrayType()) {
        int size = 1;
        ApiComment apiComment = field.getAnnotation(ApiComment.class);
        if (apiComment != null) {
            String sizeText = ApiCommentUtils.getSample(apiComment, defaultSeeClass, field.getName());
            if (StringUtils.hasText(sizeText)) {
                try {
                    size = Integer.parseInt(sizeText);
                } catch (Exception e) {
                    log.warn("List 或 Array 类型的字段上," + "@ApiComment 注解的 sample 属性应该是数字" + "(代表它在 mock 时元素的个数), sample = {}", sizeText);
                }
            }
        }
        Class<?> elementClass = getArrayElementClass(field);
        if (fieldClass.isArray()) {
            fieldValue = doCreateArray(elementClass, size, classStack);
        } else if (List.class.equals(fieldClass)) {
            fieldValue = doCreateList(elementClass, size, classStack);
        } else {
            log.warn("不支持的集合类型,目前只支持 Array OR List, class = {}, fieldName = {}" + ", fieldClass = {}", clazz, fieldName, fieldClass);
        }
    }
    try {
        setMethod.invoke(bean, fieldValue);
    } catch (Exception e) {
        log.warn("调用 setter 方法失败, \n" + "clazz = {}, \n" + "setMethod = {}, \n" + "fieldValue = {}, \n" + "失败原因: {}", clazz, setMethod, fieldValue, e.getMessage());
    }
}
Also used : PropertyDescriptor(java.beans.PropertyDescriptor) ApiComment(com.terran4j.commons.api2doc.annotations.ApiComment) ArrayList(java.util.ArrayList) List(java.util.List) ApiDataType(com.terran4j.commons.api2doc.domain.ApiDataType)

Example 3 with ApiDataType

use of com.terran4j.commons.api2doc.domain.ApiDataType in project commons by terran4j.

the class JavaBeanCodeWriter method toTypeName.

private String toTypeName(ApiResultObject result) {
    ApiDataType dataType = result.getDataType();
    Class<?> sourceType = getSourceType(result);
    ;
    String typeName = sourceType.getSimpleName();
    if (dataType.isArrayType()) {
        typeName = typeName + "[]";
    }
    return typeName;
}
Also used : ApiDataType(com.terran4j.commons.api2doc.domain.ApiDataType)

Aggregations

ApiDataType (com.terran4j.commons.api2doc.domain.ApiDataType)3 PropertyDescriptor (java.beans.PropertyDescriptor)2 ApiComment (com.terran4j.commons.api2doc.annotations.ApiComment)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1