
com.mzt.logapi.starter.diff.DefaultDiffItemsToLogContentService Maven / Gradle / Ivy
package com.mzt.logapi.starter.diff;
import com.mzt.logapi.service.IFunctionService;
import com.mzt.logapi.starter.annotation.DIffLogIgnore;
import com.mzt.logapi.starter.annotation.DiffLogAllFields;
import com.mzt.logapi.starter.annotation.DiffLogField;
import com.mzt.logapi.starter.configuration.LogRecordProperties;
import de.danielbechler.diff.node.DiffNode;
import de.danielbechler.diff.selector.ElementSelector;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.lang.NonNull;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.util.*;
/**
* @author muzhantong
* create on 2022/1/3 8:52 下午
*/
@Slf4j
@Setter
@Getter
public class DefaultDiffItemsToLogContentService implements IDiffItemsToLogContentService, BeanFactoryAware, SmartInitializingSingleton {
private IFunctionService functionService;
private final LogRecordProperties logRecordProperties;
private BeanFactory beanFactory;
public DefaultDiffItemsToLogContentService(LogRecordProperties logRecordProperties) {
this.logRecordProperties = logRecordProperties;
}
@Override
public String toLogContent(DiffNode diffNode, final Object sourceObject, final Object targetObject) {
if (!diffNode.hasChanges()) {
return "";
}
DiffLogAllFields annotation = sourceObject.getClass().getAnnotation(DiffLogAllFields.class);
StringBuilder stringBuilder = new StringBuilder();
Set set = new HashSet<>();
diffNode.visit((node, visit) -> generateAllFieldLog(sourceObject, targetObject, stringBuilder, node, annotation, set));
set.clear();
return stringBuilder.toString().replaceAll(logRecordProperties.getFieldSeparator().concat("$"), "");
}
private void generateAllFieldLog(Object sourceObject, Object targetObject, StringBuilder stringBuilder, DiffNode node,
DiffLogAllFields annotation, Set set) {
if (node.isRootNode() || node.getValueTypeInfo() != null || set.contains(node)) {
return;
}
DIffLogIgnore logIgnore = node.getFieldAnnotation(DIffLogIgnore.class);
if (logIgnore != null) {
memorandum(node, set);
return;
}
DiffLogField diffLogFieldAnnotation = node.getFieldAnnotation(DiffLogField.class);
if (annotation == null && diffLogFieldAnnotation == null) {
return;
}
String filedLogName = getFieldLogName(node, diffLogFieldAnnotation, annotation != null);
if (StringUtils.isEmpty(filedLogName)) {
return;
}
// 是否是容器类型的字段
boolean valueIsContainer = valueIsContainer(node, sourceObject, targetObject);
String functionName = diffLogFieldAnnotation != null ? diffLogFieldAnnotation.function() : "";
String logContent = valueIsContainer
? getCollectionDiffLogContent(filedLogName, node, sourceObject, targetObject, functionName)
: getDiffLogContent(filedLogName, node, sourceObject, targetObject, functionName);
if (!StringUtils.isEmpty(logContent)) {
stringBuilder.append(logContent).append(logRecordProperties.getFieldSeparator());
}
memorandum(node, set);
}
private void memorandum(DiffNode node, Set set) {
set.add(node);
if (node.hasChildren()) {
Field childrenField = ReflectionUtils.findField(DiffNode.class, "children");
assert childrenField != null;
ReflectionUtils.makeAccessible(childrenField);
Map children = (Map) ReflectionUtils.getField(childrenField, node);
assert children != null;
for (DiffNode value : children.values()) memorandum(value, set);
}
}
private String getFieldLogName(DiffNode node, DiffLogField diffLogFieldAnnotation, boolean isField) {
String filedLogName = diffLogFieldAnnotation != null ? diffLogFieldAnnotation.name() : node.getPropertyName();
if (node.getParentNode() != null) {
//获取对象的定语:比如:创建人的ID
filedLogName = getParentFieldName(node, isField) + filedLogName;
}
return filedLogName;
}
private boolean valueIsContainer(DiffNode node, Object sourceObject, Object targetObject) {
if (sourceObject != null) {
Object sourceValue = node.canonicalGet(sourceObject);
if (sourceValue == null) {
if (targetObject != null) {
return node.canonicalGet(targetObject) instanceof Collection || node.canonicalGet(targetObject).getClass().isArray();
}
} else {
return sourceValue instanceof Collection || sourceValue.getClass().isArray();
}
}
return false;
}
private String getParentFieldName(DiffNode node, boolean isField) {
DiffNode parent = node.getParentNode();
String fieldNamePrefix = "";
while (parent != null) {
DiffLogField diffLogFieldAnnotation = parent.getFieldAnnotation(DiffLogField.class);
if ((diffLogFieldAnnotation == null && !isField) || parent.isRootNode()) {
// 父节点没有配置名称且不用属性名映射,不拼接
parent = parent.getParentNode();
continue;
}
fieldNamePrefix = diffLogFieldAnnotation != null
? diffLogFieldAnnotation.name().concat(logRecordProperties.getOfWord()).concat(fieldNamePrefix)
: parent.getPropertyName().concat(logRecordProperties.getOfWord()).concat(fieldNamePrefix);
parent = parent.getParentNode();
}
return fieldNamePrefix;
}
public String getCollectionDiffLogContent(String filedLogName, DiffNode node, Object sourceObject, Object targetObject, String functionName) {
//集合走单独的diff模板
Collection
© 2015 - 2025 Weber Informatics LLC | Privacy Policy