package com.primeton.dams.utils.template;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.HibernateException;
import org.hibernate.transform.BasicTransformerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.Column;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
*
* Created by zhaopx.
* User: zhaopx
* Date: 2022/3/1
* Time: 下午6:35
* Vendor: primeton.com
*
*
*
* @author zhaopx
*/
public class DOResultTransformer extends BasicTransformerAdapter {
/**
*
*/
private static final long serialVersionUID = 1L;
private static Logger logger = LoggerFactory.getLogger(DOResultTransformer.class);
/**
* 驼峰转下划线
*/
private static Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");
@Getter
@Setter
class FieldInfo {
final String fieldName;
final Class> fieldType;
public FieldInfo(String fieldName, Class> fieldType) {
this.fieldName = fieldName;
this.fieldType = fieldType;
}
}
private final Class resultClass;
private boolean isInitialized;
private final Map aliasFieldMap = new HashMap<>();
public DOResultTransformer(@NonNull Class resultClass) {
this.resultClass = resultClass;
isInitialized = false;
}
@Override
public Object transformTuple(Object tuple[], String aliases[]) {
Object result = null;
if (!isInitialized) {
initialize(aliases);
}
// 从构造方法进入
try {
result = resultClass.newInstance();
for (int i = 0; i < tuple.length; i++) {
final FieldInfo fieldInfo = aliasFieldMap.get(StringUtils.upperCase(aliases[i]));
if(fieldInfo == null) {
continue;
}
BeanUtils.setProperty(result, fieldInfo.getFieldName(), tuple[i]);
}
} catch (Exception e) {
throw new HibernateException((new StringBuilder()).append("Could not instantiate resultclass: ").append(resultClass.getName()).toString());
}
return result;
}
private void initialize(String aliases[]) {
final Field[] declaredFields = resultClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
// final 和 static 修饰的都不是 bean 字段
if(Modifier.isFinal(declaredField.getModifiers()) || Modifier.isStatic(declaredField.getModifiers())) {
continue;
}
// 字段名称和类型
final String fieldName = declaredField.getName();
final Class> fieldType = declaredField.getType();
// 获取字段上的注解
final Column columnAnno = declaredField.getAnnotation(Column.class);
if(columnAnno == null || StringUtils.isBlank(columnAnno.name())) {
// 无注解
aliasFieldMap.put(StringUtils.upperCase(humpToLine(fieldName)), new FieldInfo(fieldName, fieldType));
} else {
// 有注解, 并且 Column name 不为 null
aliasFieldMap.put(StringUtils.upperCase(columnAnno.name()), new FieldInfo(fieldName, fieldType));
}
}
isInitialized = true;
}
/**
* 驼峰转下划线
*/
public static String humpToLine(String str) {
Matcher matcher = HUMP_PATTERN.matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
}
matcher.appendTail(sb);
return sb.toString();
}
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
DOResultTransformer that = (DOResultTransformer) o;
if (!resultClass.equals(that.resultClass))
return false;
return true;
}
public int hashCode() {
int result = resultClass.hashCode();
result = 31 * result;
return result;
}
}