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;
}
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());
}
}
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;
}
Aggregations