Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cloud.agileframework.common.util.object.ObjectUtil Maven / Gradle / Ivy
package cloud.agileframework.common.util.object;
import cloud.agileframework.common.annotation.Alias;
import cloud.agileframework.common.annotation.CompareField;
import cloud.agileframework.common.annotation.Remark;
import cloud.agileframework.common.constant.Constant;
import cloud.agileframework.common.util.clazz.ClassInfo;
import cloud.agileframework.common.util.clazz.ClassUtil;
import cloud.agileframework.common.util.clazz.FieldInfo;
import cloud.agileframework.common.util.clazz.TypeReference;
import cloud.agileframework.common.util.date.DateUtil;
import cloud.agileframework.common.util.json.JSONUtil;
import cloud.agileframework.common.util.map.MapUtil;
import cloud.agileframework.common.util.number.NumberUtil;
import cloud.agileframework.common.util.string.StringUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.SortedSet;
import java.util.StringJoiner;
import java.util.TreeSet;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.Collectors;
/**
* @author 佟盟
* 日期 2019/10/21 15:51
* 描述 TODO
* @version 1.0
* @since 1.0
*/
public class ObjectUtil extends ObjectUtils {
private static final String SERIAL_VERSION_UID = "serialVersionUID";
public static T to(Object from, TypeReference toClass) {
return to(from, toClass, true);
}
public static T to(Object from, TypeReference toClass, boolean alias) {
T result;
if (from == null) {
return null;
}
if (toClass.isEnum()) {
result = toEnum(from, toClass);
} else if (toClass.isArray()) {
result = toArray(from, toClass);
} else if (toClass.isExtendsFrom(Collection.class)) {
result = toCollection(from, toClass);
} else if (toClass.isExtendsFrom(Map.class)) {
result = toMap(from, toClass);
} else if (toClass.isWrapOrPrimitive()) {
// 基本类型转换
result = to(from, (Class) toClass.extractWrapOrPrimitive());
} else if (toClass.isExtendsFrom(String.class)) {
// 基本类型转换
result = (T) String.valueOf(from);
} else if (toClass.isExtendsFrom(Date.class)) {
if (from instanceof Date) {
if (toClass.getType() == Timestamp.class) {
result = (T) (new Timestamp(((Date) from).getTime()));
} else if (toClass.getType() == java.sql.Date.class) {
result = (T) (new java.sql.Date(((Date) from).getTime()));
} else {
result = (T) new Date(((Date) from).getTime());
}
} else {
// 日期类型转换
GregorianCalendar calendar = DateUtil.parse(from.toString());
if (calendar != null) {
result = (T) calendar.getTime();
} else {
result = null;
}
}
} else if (toClass.getType() == from.getClass()) {
// 类型相同,直接返回
result = (T) from;
} else {
// POJO类型转换
try {
result = toPOJO(from, (Class extends T>) ClassUtil.getWrapper(toClass.getType()), alias);
} catch (Exception e) {
result = null;
}
if (result == null) {
try {
Constructor construct = toClass.getConstruct(from.getClass());
result = construct.newInstance(from);
} catch (Exception ignored) {
}
}
if (result == null && ClassUtil.isPrimitive(from.getClass())) {
try {
Constructor construct = toClass.getConstruct(String.class);
result = construct.newInstance(toString(from));
} catch (Exception ignored) {
}
}
}
return result;
}
/**
* 对象转字符串
* 支持任意形式对象如容器、数组、枚举等
*
* @param from 被转换对象
* @return 转换后的字符串
*/
public static String toString(Object from) {
if (from == null) {
return null;
}
String result;
try {
Method toStringMethod = ClassUtil.getMethod(from.getClass(), "toString");
if (toStringMethod != null && toStringMethod.getDeclaringClass() != Object.class) {
return from.toString();
}
} catch (Exception ignored) {
}
if (from.getClass().isArray()) {
result = ArrayUtils.toString(from);
} else if (Collection.class.isAssignableFrom(from.getClass())) {
result = ArrayUtils.toString(((Collection>) from).toArray());
} else if (from.getClass().isEnum()) {
result = ((Enum>) from).name();
} else {
result = Objects.toString(from, null);
}
return result;
}
/**
* 转换为枚举类型
*
* @param from 被转换对象
* @param toClass 目标类型
* @param 泛型
* @return 转换后的对象
*/
private static T toEnum(Object from, TypeReference toClass) {
T result = null;
if (toClass.isEnum()) {
Class enumClass = toClass.extractEnum();
String sourceName;
if (from.getClass().isEnum()) {
sourceName = ((Enum>) from).name();
} else {
sourceName = from.toString();
}
Map map = EnumUtils.getEnumMap(enumClass);
String targetName = StringUtil.vagueMatches(sourceName, map.keySet());
if (targetName != null) {
result = (T) EnumUtils.getEnum(enumClass, targetName);
}
if (targetName == null) {
result = (T) map.values().stream().filter(a -> sourceName.endsWith(a.toString())).findFirst().orElse(null);
}
}
return result;
}
/**
* 转换为数组类型
*
* @param from 被转换对象
* @param toClass 目标类型
* @param 泛型
* @return 转换后的对象
*/
private static T toArray(Object from, TypeReference toClass) {
if (!toClass.isArray()) {
return null;
}
Object array = null;
Class> innerClass = toClass.extractArray();
if (ClassUtil.isExtendsFrom(from.getClass(), Collection.class)) {
array = Array.newInstance(innerClass, ((Collection>) from).size());
int i = 0;
for (Object node : (Collection>) from) {
Array.set(array, i++, to(node, new TypeReference(innerClass) {
}));
}
} else if (from.getClass().isArray()) {
int length = Array.getLength(from);
array = Array.newInstance(innerClass, length);
for (int i = 0; i < length; i++) {
Array.set(array, i, to(Array.get(from, i), new TypeReference(innerClass) {
}));
}
} else if (from instanceof String) {
try {
JSONArray jsonArray = JSON.parseArray((String) from);
return to(jsonArray, toClass);
} catch (Exception e) {
String[] strings = ((String) from).split(",");
return toArray(strings, toClass);
}
}
return (T) array;
}
/**
* 转换为Map类型
*
* @param from 被转换对象
* @param toClass 转换后的类型
* @param 泛型
* @return 转换后的toClass类型对象
*/
private static T toMap(Object from, TypeReference toClass) {
if (toClass.isExtendsFrom(Map.class)) {
if (ClassUtil.isExtendsFrom(from.getClass(), Collection.class)
|| from.getClass().isArray()) {
return null;
}
Map, ?> map = MapUtil.parse(from);
return (T) MapUtil.toMap((Map) map, (TypeReference>) toClass);
}
return null;
}
/**
* 转换为Collection集合类型
*
* @param from 转换对象
* @param toClass 集合类型
* @param 泛型
* @return 转换结果
*/
private static T toCollection(Object from, TypeReference toClass) {
if (!toClass.isExtendsFrom(Collection.class)) {
return null;
}
if (from instanceof String) {
try {
JSONArray array = JSON.parseArray((String) from);
return toCollection(array, toClass);
} catch (Exception e) {
String[] strings = ((String) from).split(",");
return toCollection(strings, toClass);
}
}
if (!ClassUtil.isExtendsFrom(from.getClass(), Collection.class) && !from.getClass().isArray()) {
return null;
}
Class> wrapperClass = ClassUtil.getWrapper(toClass.getType());
if (wrapperClass == null) {
return null;
}
Collection> collection;
if ((wrapperClass).isInterface()) {
if (wrapperClass == Queue.class) {
collection = new ArrayDeque<>();
} else if (wrapperClass == BlockingDeque.class) {
collection = new LinkedBlockingDeque<>();
} else if (wrapperClass == BlockingQueue.class) {
collection = new LinkedBlockingQueue<>();
} else if (wrapperClass == Set.class) {
collection = new HashSet<>();
} else if (wrapperClass == SortedSet.class) {
collection = new TreeSet<>();
} else {
collection = new ArrayList<>();
}
} else {
collection = (Collection>) ClassUtil.newInstance((wrapperClass));
}
if (collection != null) {
Type type = toClass.getType();
Type nodeType = Object.class;
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
nodeType = parameterizedType.getActualTypeArguments()[0];
}
Type finalNodeType = nodeType;
if (ClassUtil.isExtendsFrom(from.getClass(), Collection.class)) {
for (Object o : (Collection>) from) {
collection.add(to(o, new TypeReference<>(nodeType)));
}
} else if (from.getClass().isArray()) {
for (Object o : (Object[]) from) {
collection.add(to(o, new TypeReference<>(nodeType)));
}
}
}
return (T) collection;
}
/**
* 转换成POJO
*
* @param from 被转换对象
* @param toClass 转换的目标POJO类型un
* @param 泛型
* @return 转换后的POJO
*/
static T toPOJO(Object from, Class extends T> toClass, boolean alias) {
if (from == null) {
return null;
}
final Class> sourceClass = from.getClass();
if (toClass.isAssignableFrom(sourceClass)) {
return (T) from;
}
if (Map.class.isAssignableFrom(sourceClass)) {
Map map = (Map) from;
T object = getObjectFromMap(toClass, map);
if (object != null && isChange(object)) {
return object;
}
} else if (from instanceof String) {
try {
Object json = JSON.parse((String) from);
if (json instanceof JSON) {
return toPOJO(json, toClass, alias);
}
} catch (Exception ignored) {
}
} else if (sourceClass.isPrimitive() || Iterable.class.isAssignableFrom(sourceClass)) {
return null;
} else {
T object = ClassUtil.newInstance(toClass);
copyProperties(from, object, alias);
if (isChange(object)) {
return object;
}
}
return null;
}
/**
* 基本类型转换
*
* @param from 将被转换的对象
* @param toClass 转换成的目标类型
* @param 结果泛型
* @return 转换后的结果
*/
private static T to(Object from, Class toClass) {
if (from == null) {
return null;
}
Object temp = null;
if (from.getClass().isArray() && Array.getLength(from) > 0) {
from = Array.get(from, 0);
}
if (Collection.class.isAssignableFrom(from.getClass()) && !((Collection>) from).isEmpty()) {
from = ((Collection>) from).iterator().next();
}
String valueStr = from.toString();
if (NumberUtil.isNumber(toClass)) {
Number number;
if (from instanceof Boolean) {
number = (Boolean) from ? 1 : 0;
} else if ("true".equalsIgnoreCase(valueStr)) {
number = 1;
} else if ("false".equalsIgnoreCase(valueStr)) {
number = 0;
} else {
number = NumberUtils.createNumber(valueStr);
}
if (toClass == Short.class || toClass == short.class) {
temp = number.shortValue();
} else if (toClass == Integer.class || toClass == int.class) {
temp = number.intValue();
} else if (toClass == Long.class || toClass == long.class) {
temp = number.longValue();
} else if (toClass == Float.class || toClass == float.class) {
temp = number.floatValue();
} else if (toClass == Double.class || toClass == double.class) {
temp = number.doubleValue();
} else if (toClass == Byte.class || toClass == byte.class) {
temp = number.byteValue();
}
} else if (toClass == Boolean.class || toClass == boolean.class) {
if (NumberUtils.isParsable(valueStr)) {
temp = NumberUtils.createNumber(valueStr).intValue() > 0;
} else {
temp = Boolean.parseBoolean(valueStr);
}
} else if (toClass == Byte.class || toClass == byte.class) {
temp = Byte.parseByte(valueStr);
} else if (toClass == Character.class || toClass == char.class) {
char[] array = valueStr.toCharArray();
temp = array.length > 0 ? array[0] : null;
} else if (toClass == String.class && from.getClass().isPrimitive()) {
temp = valueStr;
} else if (toClass == String.class) {
try {
temp = JSON.toJSONString(from);
} catch (Exception e) {
temp = valueStr;
}
}
return (T) temp;
}
/**
* 判断pojo对象属性是否全空
* 该方法用于对象转换结果是否成功的判断
*
* @param object 判断属性是否全部为空的对象
*/
public static boolean isChange(Object object) {
if (object == null) {
return false;
}
Class> clazz = object.getClass();
try {
Object newObject = clazz.newInstance();
Set haveValueFields = ClassUtil.getAllField(clazz).stream().filter(field -> {
try {
if (SERIAL_VERSION_UID.equals(field.getName())) {
return false;
}
Object currentValue = field.get(object);
Object initValue = field.get(newObject);
return currentValue != null && !Objects.deepEquals(currentValue, initValue);
} catch (Exception e) {
return false;
}
}).collect(Collectors.toSet());
return !haveValueFields.isEmpty();
} catch (InstantiationException | IllegalAccessException e) {
return true;
}
}
/**
* 为object对象的field字段设置value值
* 方法按顺序执行以下各类属性值设置尝试,当尝试成功时立即返回
* 1、调用方法入参类型与属性field类型相同的set方法尝试
* 2、调用方法入参类型与参数value值类型相同set方法尝试
* 3、调用同名set方法
* 4、强制设值
*
* @param object 对象
* @param field 字段
* @param value 值
*/
public static void setValue(Object object, Field field, Object value) {
Class> objectClass = object.getClass();
final Class> typeTpye = field.getType();
if (value != null) {
JSONField annotation = field.getAnnotation(JSONField.class);
if (annotation != null && annotation.deserializeUsing() != null) {
try {
ObjectDeserializer deserializer = (ObjectDeserializer) ClassUtil.newInstance(annotation.deserializeUsing());
assert deserializer != null;
Object v = deserializer.deserialze(new DefaultJSONParser(JSON.toJSONString(value), ParserConfig.global, JSON.DEFAULT_PARSER_FEATURE), field.getType(), field.getName());
if (v != null) {
setValueIfNotNull(object, field, v);
return;
}
} catch (Exception ignored) {
}
}
FieldInfo fieldInfo = ClassInfo.getCache(objectClass).getFieldInfo(field);
// 如果set方法还未初始化,则开始初始化
if (fieldInfo.isNoSetters() == null) {
final String fieldName = field.getName();
String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Set allMethod = ClassUtil.getAllMethod(objectClass);
List list = allMethod.stream()
.filter(method -> setMethodName.equals(method.getName()) && method.getParameterCount() == 1)
.sorted((a, b) -> {
int result = b.getName().compareTo(a.getName());
if (result == 0) {
int aI = typeTpye == a.getParameterTypes()[0] ? 1 : 0;
int bI = typeTpye == b.getParameterTypes()[0] ? 1 : 0;
result = bI - aI;
}
return result;
})
.map(method -> {
fieldInfo.putSetter(method);
return method;
})
.collect(Collectors.toList());
// 设置该属性是否具备set方法
fieldInfo.setNoSetters(list.isEmpty());
}
// set方法初始化后,如果没有set方法之际调用set
if (Boolean.FALSE.equals(fieldInfo.isNoSetters())) {
// 如果存在set方法,则挨个调用
List setters = fieldInfo.setters();
Object initValue = null;
try {
initValue = field.get(object);
} catch (Exception ignored) {
}
for (Method setter : setters) {
try {
invokeMethodIfParamNotNull(object, setter, value);
Object newValue = field.get(object);
if (newValue != null && !newValue.equals(initValue)) {
// 新增设置值方法缓存
fieldInfo.putSetter(setter);
return;
}
} catch (Exception ignored) {
}
}
}
try {
//将来值类型与属性类型相同时,直接设置
setValueIfNotNull(object, field, value);
} catch (Exception ignored) {
}
} else {
if (!typeTpye.isPrimitive()) {
try {
field.set(object, null);
} catch (Exception ignored) {
}
}
}
}
/**
* 如果值转换不为空情况下,强调用
*
* @param object 对象
* @param method 方法
* @param value 值
*/
private static void invokeMethodIfParamNotNull(Object object, Method method, Object value) throws InvocationTargetException, IllegalAccessException {
Type[] parameterTypes = method.getGenericParameterTypes();
if (parameterTypes.length == 1) {
Object v = to(value, new TypeReference<>(parameterTypes[0]));
if (value != null && v == null) {
throw new RuntimeException();
}
method.invoke(object, v);
}
}
/**
* 如果value值转换为目标属性field类型后,不为空情况时,强设置值。否则不操作
*
* @param object 对象
* @param field 属性
* @param value 值
*/
public static void setValueIfNotNull(Object object, Field field, Object value) throws IllegalAccessException {
Object v = to(value, new TypeReference<>(field.getGenericType()));
if (value != null && v == null) {
throw new RuntimeException();
}
field.set(object, v);
}
/**
* 对象属性拷贝
*
* @param source 从哪个对象
* @param target 拷贝到哪个对象
* @param compare 拷贝方式中的属性对比方式
*
* SAME:相同
* DIFF:值不同的
* DIFF_ALL_NOT_NULL:source和target比对的字段都不空,并且值不相同的
* DIFF_SOURCE_NULL:source是空,并且值不相同的
* DIFF_TARGET_NULL:target是空,并且值不相同的
* DIFF_TARGET_DEFAULT:target属性值是默认值的,并且值不相同的
* DIFF_SOURCE_NOT_NULL_AND_TARGET_DEFAULT:target属性值是默认值的,source属性不为空的,并且值不相同的
* DIFF_SOURCE_NOT_NULL:source属性值不空的,并且值不相同的
* DIFF_TARGET_NOT_NULL:target属性值不空的,并且值不相同的
*/
public static void copyProperties(Object source, Object target, Compare compare) {
copyProperties(source, target, Constant.RegularAbout.BLANK, Constant.RegularAbout.BLANK, new String[]{}, ContainOrExclude.EXCLUDE, compare, false);
}
/**
* 通过不同的比较方式,获取同名属性集合
*
* @param source 比较对象
* @param target 比较对象
* @param compare 比对方式
* @return 属性名集合
*/
private static Map> getSameField(Object source, Object target, String prefix, String suffix, Compare compare, boolean isAlias) {
Map> result = Maps.newConcurrentMap();
if (ObjectUtils.isEmpty(source) || ObjectUtils.isEmpty(target)) {
return result;
}
if (isAlias) {
result = getSameFieldByAlias(source.getClass(), target.getClass(), prefix, suffix);
} else {
result = getSameFieldByBlurry(source.getClass(), target.getClass(), prefix, suffix);
}
if (result.isEmpty()) {
return result;
}
//根据比较规则,过滤字段映射情况
parseCompare(source, target, compare, result);
return result;
}
/**
* 处理Compare,更具Compare比较规则,提取字段映射
*
* @param source 从对象
* @param target 到对象
* @param compare 比较规则
* @param result 字段映射情况,key为从对象字段,value为到对象字段集合
*/
private static void parseCompare(Object source, Object target, Compare compare, Map> result) {
Object targetNew = null;
try {
targetNew = target.getClass().newInstance();
} catch (Exception ignored) {
}
Object finalTargetNew = targetNew;
Iterator>> resultIt = result.entrySet().iterator();
while (resultIt.hasNext()) {
Map.Entry> e = resultIt.next();
Field toField = e.getKey();
Set fromFields = e.getValue();
boolean is = false;
for (Field fromField : fromFields) {
Object sourceValue = getFieldValue(source, fromField);
Object targetValue = getFieldValue(target, toField);
switch (compare) {
case DIFF_ALL_NOT_NULL:
if (sourceValue != null && targetValue != null && !equals(sourceValue, targetValue)) {
continue;
}
break;
case DIFF_TARGET_NULL:
if (sourceValue != null && targetValue == null) {
continue;
}
break;
case DIFF_SOURCE_NULL:
if (sourceValue == null && targetValue != null) {
continue;
}
break;
case DIFF_SOURCE_NOT_NULL:
if (sourceValue != null && !equals(sourceValue, targetValue)) {
continue;
}
break;
case DIFF_TARGET_NOT_NULL:
if (targetValue != null && !equals(sourceValue, targetValue)) {
continue;
}
break;
case DIFF_SOURCE_NOT_NULL_AND_TARGET_DEFAULT:
if (finalTargetNew == null) {
throw new RuntimeException(String.format("目标对象创建失败,请检查类“%s”是否包含空参构造函数", target.getClass()));
} else if (sourceValue != null && !equals(sourceValue, targetValue) && equals(getFieldValue(finalTargetNew, toField), targetValue)) {
continue;
}
break;
case DIFF_TARGET_DEFAULT:
if (finalTargetNew == null) {
throw new RuntimeException(String.format("目标对象创建失败,请检查类“%s”是否包含空参构造函数", target.getClass()));
} else if (!equals(sourceValue, targetValue) && equals(getFieldValue(finalTargetNew, toField), targetValue)) {
continue;
}
break;
case DIFF:
if (!equals(sourceValue, targetValue)) {
continue;
}
break;
case SAME:
if (equals(sourceValue, targetValue)) {
continue;
}
break;
default:
}
is = true;
}
if (is) {
resultIt.remove();
}
}
}
/**
* 判断俩对象是否相等
*
* @param object1 对象一
* @param object2 对象二
* @return 是否
*/
public static boolean equals(Object object1, Object object2) {
if (object1 == object2) {
return true;
} else {
return object1 != null && object1.equals(object2);
}
}
public static Map> getSameFieldByBlurry(Class> sourceClass, Class> targetClass) {
return getSameFieldByBlurry(sourceClass, targetClass, Constant.RegularAbout.BLANK, Constant.RegularAbout.BLANK);
}
/**
* 模糊匹配方式匹配,提取两个类型属性之间得映射关系
*
* @param sourceClass 比较对象
* @param targetClass 比较对象
* @param prefix 只处理属性前缀为prefix的属性
* @param suffix 只处理属性后缀为suffix的属性
* @return 同名属性集合
*/
public static Map> getSameFieldByBlurry(Class> sourceClass, Class> targetClass, String prefix, String suffix) {
Map> result = Maps.newConcurrentMap();
if (ObjectUtils.isEmpty(sourceClass) || ObjectUtils.isEmpty(targetClass)) {
return result;
}
String finalPrefix = prefix == null ? "" : prefix;
String finalSuffix = suffix == null ? "" : suffix;
if (sourceClass == targetClass) {
for (Field field : ClassUtil.getAllField(sourceClass)) {
if (field.getName().startsWith(finalPrefix) && field.getName().endsWith(finalPrefix)) {
result.put(field, Sets.newHashSet(field));
}
}
} else {
for (Field toField : ClassUtil.getAllField(targetClass)) {
String name = toField.getName();
Field fromField = ClassUtil.getField(sourceClass, name);
if (fromField != null && fromField.getName().startsWith(finalPrefix) && fromField.getName().endsWith(finalSuffix)) {
Set set = result.get(fromField);
if (set == null) {
set = Sets.newHashSet();
}
set.add(toField);
result.put(fromField, set);
}
}
}
return result;
}
public static Map> getSameFieldByAlias(Class> sourceClass, Class> targetClass) {
return getSameFieldByAlias(sourceClass, targetClass, Constant.RegularAbout.BLANK, Constant.RegularAbout.BLANK);
}
/**
* 根据别名、属性名,提取两个类型属性映射关系
*
* @param sourceClass 从
* @param targetClass 到
* @param prefix 只处理属性前缀为prefix的属性
* @param suffix 只处理属性后缀为suffix的属性
* @return 属性映射关系
*/
public static Map> getSameFieldByAlias(Class> sourceClass, Class> targetClass, String prefix, String suffix) {
Map> map = Maps.newConcurrentMap();
if (ObjectUtils.isEmpty(sourceClass) || ObjectUtils.isEmpty(targetClass)) {
return map;
}
String finalPrefix = prefix == null ? "" : prefix;
String finalSuffix = suffix == null ? "" : suffix;
Map> sourceMap = parseFieldAlias(sourceClass);
Map> targetMap = parseFieldAlias(targetClass);
// sourceMap.entrySet().stream().filter(e -> {
// final String name = e.getKey().getName();
// return name.startsWith(finalPrefix) && name.endsWith(finalSuffix);
// }).forEach(e -> {
// Set sourceAlias = e.getValue();
// Set set = targetMap.entrySet().stream().filter(te ->
// !CollectionUtils.retainAll(te.getValue(), sourceAlias).isEmpty()
// ).map(Map.Entry::getKey).collect(Collectors.toSet());
// map.put(e.getKey(), set);
// });
targetMap.entrySet().stream().filter(e -> {
final String name = e.getKey().getName();
return name.startsWith(finalPrefix) && name.endsWith(finalSuffix);
}).forEach(e -> {
Set targetAlias = e.getValue();
Set set = new HashSet<>();
for (Map.Entry> te : sourceMap.entrySet()) {
if (!CollectionUtils.retainAll(te.getValue(), targetAlias).isEmpty()) {
Field key = te.getKey();
set.add(key);
}
}
map.put(e.getKey(), set);
});
return map;
}
/**
* 整理类属性的别名
*
* @param sourceClass 将被整理的类
* @return
*/
public static Map> parseFieldAlias(Class> sourceClass) {
Map> sourceMap = Maps.newConcurrentMap();
Set> sourceAnnotations = ClassUtil.getAllEntityAnnotation(sourceClass, Alias.class);
for (Field field : ClassUtil.getAllField(sourceClass)) {
ClassUtil.Target an = null;
for (ClassUtil.Target sourceAnnotation : sourceAnnotations) {
if (sourceAnnotation.getMember() == field) {
an = sourceAnnotation;
break;
}
}
Set aliases;
if (an != null) {
aliases = Sets.newHashSet(an.getAnnotation().value());
aliases.add(field.getName());
} else {
aliases = Sets.newHashSet(field.getName());
}
JSONField jsonField = ClassUtil.getFieldAnnotation(sourceClass, field.getName(), JSONField.class);
if (jsonField != null && !StringUtils.isBlank(jsonField.name())) {
aliases.add(jsonField.name());
}
sourceMap.put(field, aliases);
}
return sourceMap;
}
/**
* 对象属性拷贝
*
* @param source 从哪个对象
* @param target 拷贝到哪个对象
* @param arguments 属性名集合
* @param containOrExclude INCLUDE时,则拷贝arguments中的属性;EXCLUDE时,则拷贝arguments以外的属性。
*/
public static void copyProperties(Object source, Object target, String[] arguments, ContainOrExclude containOrExclude) {
copyProperties(source, target, Constant.RegularAbout.BLANK, Constant.RegularAbout.BLANK, arguments, containOrExclude, Compare.DIFF, false);
}
/**
* 对象属性拷贝
*
* @param source 从哪个对象
* @param target 拷贝到哪个对象
* @param prefix 要拷贝属性的前缀,仅拷贝符合该前缀的属性
* @param suffix 要拷贝属性的后缀,仅拷贝符合该后缀的属性
*/
public static void copyProperties(Object source, Object target, String prefix, String suffix) {
copyProperties(source, target, prefix, suffix, new String[]{}, ContainOrExclude.EXCLUDE, Compare.DIFF, false);
}
/**
* 复制对象属性
* 仅拷贝属性值不相同属性
*
* @param source 原对象
* @param target 新对象
*/
public static void copyProperties(Object source, Object target) {
copyProperties(source, target, Constant.RegularAbout.BLANK, Constant.RegularAbout.BLANK, new String[]{}, ContainOrExclude.EXCLUDE, Compare.DIFF, false);
}
/**
* 复制对象属性
* 仅拷贝属性值不相同属性
*
* @param source 原对象
* @param target 新对象
* @param alias 是否识别别名注解@Alias
*/
public static void copyProperties(Object source, Object target, boolean alias) {
copyProperties(source, target, Constant.RegularAbout.BLANK, Constant.RegularAbout.BLANK, new String[]{}, ContainOrExclude.EXCLUDE, Compare.DIFF, alias);
}
/**
* 复制对象属性
*
* @param source 从哪个对象
* @param target 复制到哪个对象
* @param prefix 要拷贝属性的前缀,仅拷贝符合该前缀的属性
* @param suffix 要拷贝属性的后缀,仅拷贝符合该后缀的属性
* @param arguments 属性列表
* @param containOrExclude 包含或排除
*/
public static void copyProperties(Object source, Object target, String prefix, String suffix, String[] arguments, ContainOrExclude containOrExclude, Compare compare, boolean isAlias) {
if (ObjectUtils.isEmpty(source) || ObjectUtils.isEmpty(target)) {
return;
}
Map> argumentsMap = getSameField(source, target, prefix, suffix, compare, isAlias);
argumentsMap.entrySet()
.forEach(e -> {
try {
Field toField = e.getKey();
if (e.getValue().isEmpty()) {
Alias alias = ClassUtil.getFieldAnnotation(target.getClass(), toField.getName(), Alias.class);
if (alias != null) {
for (String alia : alias.value()) {
Object value = JSONUtil.pathGet(alia, source);
Type type = toField.getGenericType();
TypeReference typeReference = new TypeReference<>(type);
if (value != null) {
value = to(value, typeReference);
}
setValue(target, toField, value);
}
}
return;
}
for (Field fromField : e.getValue()) {
switch (containOrExclude) {
case EXCLUDE:
if (ArrayUtils.contains(arguments, fromField.getName())) {
return;
}
break;
case INCLUDE:
if (!ArrayUtils.contains(arguments, fromField.getName())) {
return;
}
break;
default:
}
Object value = fromField.get(source);
Type type = toField.getGenericType();
TypeReference typeReference = new TypeReference<>(type);
if (value != null) {
value = to(value, typeReference);
}
setValue(target, toField, value);
}
} catch (Exception ignored) {
}
});
}
/**
* 取属性值
* 取值方式为优先使用属性get方法,当未定义get方法时,则直接通过反射获取属性值
*
* @param o 对象
* @param fieldName 属性名
* @return 属性值
*/
public static Object getFieldValue(Object o, String fieldName) {
if (o == null) {
return null;
}
Field field = ClassUtil.getField(o.getClass(), fieldName);
if (field == null) {
return null;
}
return getFieldValue(o, field);
}
/**
* 取属性值
* 取值方式为优先使用属性get方法,当未定义get方法时,则直接通过反射获取属性值
*
* @param o 对象
* @param field 属性
* @return 值
*/
public static Object getFieldValue(Object o, Field field) {
if (field == null) {
return null;
}
final FieldInfo fieldInfo = ClassInfo.getCache(o.getClass()).getFieldInfo(field);
// 判断get方法是否初始化
if (fieldInfo.isNoGetters() == null) {
List methods;
final String fieldName = field.getName();
String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
if (field.getType() == Boolean.TYPE) {
String getMethodName2 = "is" + StringUtil.toUpperName(field.getName());
methods = ClassInfo.getCache(o.getClass()).getAllMethod().stream().filter(method ->
(method.getName().equals(getMethodName) || method.getName().equals(getMethodName2)) && method.getParameterCount() == 0)
.map(method -> {
fieldInfo.putGetter(method);
return method;
}).collect(Collectors.toList());
} else {
methods = ClassInfo.getCache(o.getClass()).getAllMethod().stream().filter(method ->
method.getName().equals(getMethodName) && method.getParameterCount() == 0)
.map(method -> {
fieldInfo.putGetter(method);
return method;
}).collect(Collectors.toList());
}
if (!methods.isEmpty()) {
for (Method method : methods) {
try {
Object v = method.invoke(o);
//调整getter优先级
fieldInfo.putGetter(method);
return v;
} catch (Exception ignored) {
}
}
} else {
fieldInfo.setNoGetters(true);
}
}
if (Boolean.FALSE.equals(fieldInfo.isNoGetters())) {
List getters = fieldInfo.getters();
for (Method getter : getters) {
try {
Object v = getter.invoke(o);
//调整getter优先级
fieldInfo.putGetter(getter);
return v;
} catch (Exception ignored) {
}
}
}
try {
return field.get(o);
} catch (Exception ignored) {
return null;
}
}
/**
* 从Map对象中获取指定类型对象,也可以达到Map转POJO对象的效果
*
* @param clazz 想要获取的对象类型
* @param map Map结构属性集合
* @return 返回指定对象类型对象
*/
public static T getObjectFromMap(Class clazz, Map, ?> map) {
return getObjectFromMap(clazz, map, "", "");
}
/**
* 从Map对象中获取指定类型对象,也可以达到Map转POJO对象的效果
*
* @param clazz 想要获取的对象类型
* @param map Map结构属性集合
* @param prefix 前缀,转换前先根据前缀过滤Map的key值,仅针对过滤后的Map.Entry做转换操作
* @return 返回指定对象类型对象
*/
public static T getObjectFromMap(Class clazz, Map map, String prefix) {
return getObjectFromMap(clazz, map, prefix, "");
}
/**
* 从Map对象中获取指定类型对象,也可以达到Map转POJO对象的效果
*
* @param clazz 想要获取的对象类型
* @param map Map结构属性集合
* @param prefix 前缀,转换前先根据前缀过滤Map的key值,仅针对过滤后的Map.Entry做转换操作
* @param suffix 后缀,转换前先根据缀过滤Map的key值,仅针对过滤后的Map.Entry做转换操作
* @return 返回指定对象类型对象
*/
public static T getObjectFromMap(Class clazz, Map, ?> map, String prefix, String suffix) {
if (Map.class.isAssignableFrom(clazz)) {
return (T) map;
}
if (!ObjectUtils.isEmpty(map)) {
T object = ClassUtil.newInstance(clazz);
Set fields = ClassUtil.getAllField(clazz);
fields.forEach(field -> {
String key = coverFieldNameToMapKey(clazz, field, prefix, suffix, map);
if (key != null) {
try {
Object value = map.get(key);
setValue(object, field, value);
} catch (IllegalArgumentException ignored) {
}
}
});
if (!isAllNullValidity(object)) {
return object;
}
}
return null;
}
/**
* 在map集中,根据field属性名字或Alias别名注解,推断与属性对应的key值
* 该方法常用于Map转POJO对象使用,如持久层组件查询结果为List>结构转List时使用
*
* @param clazz 类
* @param field 字段
* @param prefix 前缀
* @param suffix 后缀
* @param map 集合
* @return key值
*/
public static String coverFieldNameToMapKey(Class> clazz, Field field, String prefix, String suffix, Map, ?> map) {
String key = null;
String propertyName = prefix + field.getName() + suffix;
if (map.containsKey(propertyName)) {
return propertyName;
}
Alias column = null;
try {
column = getAllEntityPropertyAnnotation(clazz, field, Alias.class);
} catch (Exception ignored) {
}
if (column != null) {
for (String alias : column.value()) {
if (map.containsKey(alias)) {
key = alias;
break;
}
}
}
if (key != null) {
return key;
}
Set keys = new HashSet<>();
for (Object o : map.keySet()) {
String toString = o.toString();
keys.add(toString);
}
key = StringUtil.vagueMatches(propertyName, keys);
if (key != null) {
return key;
}
if (column != null) {
for (String alias : column.value()) {
key = StringUtil.vagueMatches(alias, keys);
if (key != null) {
break;
}
}
}
return key;
}
/**
* 获取所有属性注解,包括属性对应的get方法,其中能类似于JPA注解的解析过程
*
* @param clazz 类
* @param field 属性
* @param annotation 要取的注解
* @return 注解结果集
*/
public static T getAllEntityPropertyAnnotation(Class> clazz, Field field, Class annotation) {
T result = null;
T fieldDeclaredAnnotations = field.getDeclaredAnnotation(annotation);
if (fieldDeclaredAnnotations != null) {
return fieldDeclaredAnnotations;
}
T fieldAnnotations = field.getAnnotation(annotation);
if (fieldAnnotations != null) {
return fieldAnnotations;
}
String getMethodName = String.format("get%s", StringUtil.toUpperName(field.getName()));
try {
Method declaredMethod = clazz.getDeclaredMethod(getMethodName);
T methodDeclaredAnnotations = declaredMethod.getDeclaredAnnotation(annotation);
if (methodDeclaredAnnotations != null) {
return methodDeclaredAnnotations;
}
} catch (Exception ignored) {
}
try {
Method method = clazz.getMethod(getMethodName);
T methodAnnotations = method.getAnnotation(annotation);
if (methodAnnotations != null) {
return methodAnnotations;
}
} catch (Exception ignored) {
}
return result;
}
/**
* 判断对象属性经过初始化后,是否改变
*
* @param object 对象
*/
public static boolean isAllNullValidity(Object object) {
Class> clazz = object.getClass();
try {
Object newObject = clazz.newInstance();
Set haveValueFields = ClassUtil.getAllField(clazz).stream().filter(field -> {
try {
if (SERIAL_VERSION_UID.equals(field.getName())) {
return false;
}
if (!field.isAccessible()) {
field.setAccessible(true);
}
Object currentValue = field.get(object);
Object initValue = field.get(newObject);
return currentValue != null && currentValue != initValue;
} catch (Exception e) {
return false;
}
}).collect(Collectors.toSet());
return haveValueFields.isEmpty();
} catch (InstantiationException | IllegalAccessException e) {
return false;
}
}
/**
* 对象的所有属性都设置为空
*
* @param object 对象
*/
public static void setAllFieldNull(Object object) {
if (object == null) {
return;
}
for (Field field : ClassUtil.getAllField(object.getClass())) {
try {
if (SERIAL_VERSION_UID.equals(field.getName())) {
continue;
}
if (!field.isAccessible()) {
field.setAccessible(true);
}
field.set(object, null);
} catch (Exception ignored) {
}
}
}
/**
* 对象转json字符串,类似于自定义的toString
*
* @param o pojo对象
* @param exclude 排除转换的字段名字
* @return 字符串
*/
public static String objectToString(Object o, String... exclude) {
Class> clazz = o.getClass();
StringBuilder target = new StringBuilder(clazz.getSimpleName()).append("{");
Set fields = ClassUtil.getAllField(clazz);
int i = 0;
for (Field field : fields) {
try {
if (ArrayUtils.contains(exclude, field.getName())) {
i++;
continue;
}
if (!field.isAccessible()) {
field.setAccessible(true);
}
if (i != 0) {
target.append(", ");
}
target.append(field.getName()).append("='").append(field.get(o));
if (i == fields.size() - 1) {
target.append('}');
} else {
target.append('\'');
}
} catch (IllegalAccessException e) {
continue;
}
i++;
}
return target.toString();
}
/**
* 对象转Map结构,属性名在Map结构中映射为下划线式key值
*
* @param o 对象
* @return Map
*/
public static Map getUnderlineMapFromObject(Object o, String... excludeField) {
Set fields = ClassUtil.getAllField(o.getClass());
Set set = new HashSet<>();
for (Field field1 : fields) {
if (!ArrayUtils.contains(excludeField, field1.getName())) {
set.add(field1);
}
}
fields = set;
Map result = new HashMap<>(fields.size());
if (!fields.isEmpty()) {
fields.forEach(field -> {
String key = StringUtil.toUnderline(field.getName());
try {
if (!field.isAccessible()) {
field.setAccessible(true);
}
result.put(key, field.get(o));
} catch (IllegalAccessException ignored) {
}
});
}
return result;
}
/**
* 对象集转Map结构,属性名在Map结构中映射为下划线式key值
*
* @param list 对象集合
* @return map集合
*/
public static List> getUnderlineMapFromListObject(Iterable list) {
List> result = new ArrayList<>();
if (list != null) {
for (Object o : list) {
result.add(getUnderlineMapFromObject(o));
}
}
return result;
}
/**
* 比较两个对象属性是否相同
*
* @param source 源对象
* @param target 目标对象
* @return 是否相同
*/
public static boolean compare(Object source, Object target) {
return isEmpty(source) && isEmpty(target) || source.equals(target);
}
/**
* 获取两个同类型对象的同属性不同值信息列表
* 该方法可用于比较两个同类型对象的不同情况,例如可用于表变动操作日志记录
*
* @param source 源对象
* @param target 目标对象
* @param excludeProperty 排除的属性
* @return 值不相同的属性列表
*/
public static List getDifferenceProperties(Object source, Object target, String... excludeProperty) {
List result = new ArrayList<>();
if (source == null && target == null) {
return result;
}
Set sourceFields = source == null ? Sets.newHashSetWithExpectedSize(0) : ClassUtil.getAllField(source.getClass());
Set targetFields = target == null ? Sets.newHashSetWithExpectedSize(0) : ClassUtil.getAllField(target.getClass());
// 提取要处理比较的所有属性
Set willResolveFieldNames = new HashSet<>();
for (Set fields : Arrays.asList(sourceFields, targetFields)) {
for (Field field : fields) {
String a = field.getName();
if (!ArrayUtils.contains(excludeProperty, a)) {
willResolveFieldNames.add(a);
}
}
}
// 属性逐个比较
for (String fieldName : willResolveFieldNames) {
DifferentField differentField = resolve(source, target, fieldName);
// 过滤掉相同的属性
if (differentField == null) {
continue;
}
if (differentField instanceof DifferentRefField) {
result.addAll(((DifferentRefField) differentField).extractRef());
continue;
}
result.add(differentField);
}
return result;
}
/**
* 提取中文描述信息
*
* @param source 比较对象
* @param target 比较对象
* @param excludeProperty 排除的属性
* @return 描述信息
*/
public static String getDifferencePropertiesDesc(Object source, Object target, String... excludeProperty) {
List difFields = getDifferenceProperties(source, target, excludeProperty);
StringJoiner joiner = new StringJoiner(Constant.RegularAbout.NEW_LINE);
for (DifferentField difField : difFields) {
String describe = difField.describe();
joiner.add(describe);
}
return joiner.toString();
}
/**
* 比较两个对象的fieldName属性,source与target可以为不同的两种类型对象,属性不存在与属性值为空等效
*
* @param source 比较对象
* @param target 比较对象
* @param fieldName 要比较的属性名
* @return 差异信息
*/
public static DifferentField resolve(Object source, Object target, String fieldName) {
DifferentField result = null;
if (source == null && target == null) {
return result;
}
// 要比较的属性值
Object sourceValue = getFieldValue(source, fieldName);
Object targetValue = getFieldValue(target, fieldName);
if (sourceValue == null && targetValue == null) {
return result;
}
if (Objects.equals(sourceValue, targetValue)) {
return result;
}
// 提取属性
Field sourceField = getField(source, fieldName);
Field targetField = getField(target, fieldName);
String remark;
try {
remark = resolveLogField(source, target, fieldName);
} catch (DifferentField.LogFieldIgnoreException e) {
// 忽略属性
return result;
}
// 判断引用类型属性比较
CompareField sourceCompareField = ObjectUtil.getFieldAnnotation(source, fieldName, CompareField.class);
CompareField targetCompareField = ObjectUtil.getFieldAnnotation(target, fieldName, CompareField.class);
if (sourceCompareField != null || targetCompareField != null) {
List ref = getDifferenceProperties(sourceValue, targetValue);
return new DifferentRefField(fieldName, remark, Object.class, ref,
sourceCompareField == null ? targetCompareField.ignoreParentName() : sourceCompareField.ignoreParentName(),
sourceCompareField == null ? targetCompareField.ignoreParentRemark() : sourceCompareField.ignoreParentRemark());
}
if (source == null) {
// source空
// sourceValue空
// target非空
// targetValue非空
if (targetField.getType().isArray() || Collection.class.isAssignableFrom(targetField.getType())) {
result = new DifferentCollectionField(fieldName, remark, targetField.getType());
((DifferentCollectionField) result).setAdd(to(targetValue, new TypeReference>() {
}));
} else {
result = new DifferentSimpleField(fieldName, remark, targetField.getType());
((DifferentSimpleField) result).setNewValue(targetValue);
}
} else if (target == null) {
// source非空
// sourceValue非空
// target空
// targetValue空
if (sourceField.getType().isArray() || Collection.class.isAssignableFrom(sourceField.getType())) {
result = new DifferentCollectionField(fieldName, remark, sourceField.getType());
((DifferentCollectionField) result).setAdd(to(sourceValue, new TypeReference>() {
}));
} else {
result = new DifferentSimpleField(fieldName, remark, sourceField.getType());
((DifferentSimpleField) result).setNewValue(sourceValue);
}
} else if (targetValue == null) {
// source非空
// sourceValue非空
// target非空
// targetValue空
if (sourceField != null && targetField != null && (sourceField.getType().isArray() || Collection.class.isAssignableFrom(sourceField.getType()))
&& (targetField.getType().isArray() || Collection.class.isAssignableFrom(targetField.getType()))) {
result = new DifferentCollectionField(fieldName, remark, sourceField.getType());
((DifferentCollectionField) result).setDel(to(sourceValue, new TypeReference>() {
}));
} else {
result = new DifferentSimpleField(fieldName, remark, sourceField.getType());
((DifferentSimpleField) result).setOldValue(sourceValue);
}
} else if (sourceValue == null) {
// source非空
// sourceValue空
// target非空
// targetValue非空
if (sourceField != null && targetField != null && (sourceField.getType().isArray() || Collection.class.isAssignableFrom(sourceField.getType()))
&& (targetField.getType().isArray() || Collection.class.isAssignableFrom(targetField.getType()))) {
result = new DifferentCollectionField(fieldName, remark, sourceField.getType());
((DifferentCollectionField) result).setAdd(to(targetValue, new TypeReference>() {
}));
} else {
result = new DifferentSimpleField(fieldName, remark, targetField.getType());
((DifferentSimpleField) result).setNewValue(targetValue);
}
} else {
// source非空
// sourceValue非空
// target非空
// targetValue非空
if ((sourceField.getType().isArray() || Collection.class.isAssignableFrom(sourceField.getType()))
&& (targetField.getType().isArray() || Collection.class.isAssignableFrom(targetField.getType()))) {
List formatSourceValue = to(sourceValue, new TypeReference>() {
});
List formatTargetValue = to(targetValue, new TypeReference>() {
});
List add = formatTargetValue == null ? Lists.newArrayList() : formatTargetValue;
List del = formatSourceValue == null ? Lists.newArrayList() : formatSourceValue;
Iterator it = add.iterator();
while (it.hasNext()) {
Object node = it.next();
if (del.contains(node)) {
del.remove(node);
it.remove();
}
}
if (add.equals(del)) {
return result;
}
result = new DifferentCollectionField(fieldName, remark, sourceField.getType());
((DifferentCollectionField) result).setAdd(add);
((DifferentCollectionField) result).setDel(del);
} else {
result = new DifferentSimpleField(fieldName, remark, sourceField.getType());
((DifferentSimpleField) result).setOldValue(sourceValue);
((DifferentSimpleField) result).setNewValue(targetValue);
}
}
return result;
}
/**
* 获取对象的某个属性上的注解,包裹属性的get方法上的注解
*
* @param object 对象
* @param fieldName 属性名
* @param annotationClass 注解类型
* @param 注解类型
* @return 属性或属性的get方法上的注解
*/
public static A getFieldAnnotation(Object object, String fieldName, Class annotationClass) {
if (object == null) {
return null;
}
return ClassUtil.getFieldAnnotation(object.getClass(), fieldName, annotationClass);
}
/**
* 处理LogField注解
*
* @param source 被比较的两个对象的第一个对象属性
* @param target 被比较的两个对象的第二个对象属性
* @param fieldName 属性名
* @return 提取到的注解value值
* @throws DifferentField.LogFieldIgnoreException 忽略
*/
private static String resolveLogField(Object source, Object target, String fieldName) throws DifferentField.LogFieldIgnoreException {
boolean sourceFieldIgnore = false;
boolean targetFieldIgnore = false;
StringBuilder remark = new StringBuilder();
Remark sourceLogField = getFieldAnnotation(source, fieldName, Remark.class);
if (sourceLogField != null && !sourceLogField.ignoreCompare()) {
remark.append(sourceLogField.value());
} else if (sourceLogField != null) {
sourceFieldIgnore = true;
}
Remark targetLogField = getFieldAnnotation(target, fieldName, Remark.class);
if (targetLogField != null && !targetLogField.ignoreCompare() && !targetLogField.value().equals(remark.toString())) {
if (remark.length() == 0) {
remark.append(targetLogField.value());
} else {
remark.append("(").append(targetLogField.value()).append(")");
}
} else if (targetLogField != null) {
targetFieldIgnore = true;
}
if (sourceFieldIgnore && targetFieldIgnore) {
throw DifferentField.LogFieldIgnoreException.LOG_FIELD_IGNORE_EXCEPTION;
}
return remark.length() == 0 ? fieldName : remark.toString();
}
/**
* 提取对象的属性
*
* @param object 对象
* @param fieldName 属性值
* @return 属性
*/
public static Field getField(Object object, String fieldName) {
if (object == null) {
return null;
}
return ClassUtil.getField(object.getClass(), fieldName);
}
/**
* 比较两个对象属性是否相同
*
* @param source 源对象
* @param target 目标对象
* @param excludeProperty 排除的比较属性
* @return 是否相同
*/
public static boolean compareValue(Object source, Object target, String... excludeProperty) {
if (isEmpty(source)) {
return isEmpty(target);
} else {
if (isEmpty(target)) {
return false;
}
List list = getDifferenceProperties(source, target, excludeProperty);
return ObjectUtils.isEmpty(list);
}
}
/**
* 只比较source中不为空的字段
*
* @param source 原对象
* @param target 目标对象
* @return 是否
*/
public static boolean compareOfNotNull(Object source, Object target) {
Field[] fields = source.getClass().getDeclaredFields();
for (Field field : fields) {
if (SERIAL_VERSION_UID.equals(field.getName())) {
continue;
}
try {
if (!field.isAccessible()) {
field.setAccessible(true);
}
Object sourceValue = field.get(source);
if (sourceValue == null) {
continue;
}
Object targetValue = field.get(target);
if (!sourceValue.equals(targetValue)) {
return false;
}
} catch (Exception ignored) {
}
}
return true;
}
/**
* 值比对方式
*/
public enum Compare {
/**
* 相同
*/
SAME,
/**
* 值不同的
*/
DIFF,
/**
* source和target比对的字段都不空,并且值不相同的
*/
DIFF_ALL_NOT_NULL,
/**
* source是空,并且值不相同的
*/
DIFF_SOURCE_NULL,
/**
* target是空,并且值不相同的
*/
DIFF_TARGET_NULL,
/**
* target属性值是默认值的,并且值不相同的
*/
DIFF_TARGET_DEFAULT,
/**
* target属性值是默认值的,source属性不为空的,并且值不相同的
*/
DIFF_SOURCE_NOT_NULL_AND_TARGET_DEFAULT,
/**
* source属性值不空的,并且值不相同的
*/
DIFF_SOURCE_NOT_NULL,
/**
* target属性值不空的,并且值不相同的
*/
DIFF_TARGET_NOT_NULL
}
/**
* 包含或者排除
*/
public enum ContainOrExclude {
/**
* 包含
*/
INCLUDE,
/**
* 不包含
*/
EXCLUDE
}
}