All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.magictools.core.bean.copier.CopyOptions Maven / Gradle / Ivy

Go to download

magic-tools 是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

The newest version!
package com.magictools.core.bean.copier;

import com.magictools.core.convert.Convert;
import com.magictools.core.convert.TypeConverter;
import com.magictools.core.lang.Editor;
import com.magictools.core.lang.func.Func1;
import com.magictools.core.lang.func.LambdaUtil;
import com.magictools.core.util.ArrayUtil;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;

/**
 * 属性拷贝选项
* 包括:
* 1、限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类
* 2、是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null
* 3、忽略的属性列表,设置一个属性列表,不拷贝这些属性值
* * @author Looly */ public class CopyOptions implements Serializable { private static final long serialVersionUID = 1L; /** * 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性,例如一个类我只想复制其父类的一些属性,就可以将editable设置为父类
* 如果目标对象是Map,源对象是Bean,则作用于源对象上 */ protected Class editable; /** * 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null */ protected boolean ignoreNullValue; /** * 属性过滤器,断言通过的属性才会被复制
* 断言参数中Field为源对象的字段对象,如果源对象为Map,使用目标对象,Object为源对象的对应值 */ private BiPredicate propertiesFilter; /** * 是否忽略字段注入错误 */ protected boolean ignoreError; /** * 是否忽略字段大小写 */ protected boolean ignoreCase; /** * 字段属性编辑器,用于自定义属性转换规则,例如驼峰转下划线等
* 规则为,{@link Editor#edit(Object)}属性为源对象的字段名称或key,返回值为目标对象的字段名称或key */ private Editor fieldNameEditor; /** * 字段属性值编辑器,用于自定义属性值转换规则,例如null转""等 */ protected BiFunction fieldValueEditor; /** * 是否支持transient关键字修饰和@Transient注解,如果支持,被修饰的字段或方法对应的字段将被忽略。 */ protected boolean transientSupport = true; /** * 是否覆盖目标值,如果不覆盖,会先读取目标对象的值,非{@code null}则写,否则忽略。如果覆盖,则不判断直接写 */ protected boolean override = true; /** * 自定义类型转换器,默认使用全局万能转换器转换 */ protected TypeConverter converter = (type, value) -> Convert.convertWithCheck(type, value, null, ignoreError); //region create /** * 创建拷贝选项 * * @return 拷贝选项 */ public static CopyOptions create() { return new CopyOptions(); } /** * 创建拷贝选项 * * @param editable 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性 * @param ignoreNullValue 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null * @param ignoreProperties 忽略的属性列表,设置一个属性列表,不拷贝这些属性值 * @return 拷贝选项 */ public static CopyOptions create(Class editable, boolean ignoreNullValue, String... ignoreProperties) { return new CopyOptions(editable, ignoreNullValue, ignoreProperties); } //endregion /** * 构造拷贝选项 */ public CopyOptions() { } /** * 构造拷贝选项 * * @param editable 限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性 * @param ignoreNullValue 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null * @param ignoreProperties 忽略的目标对象中属性列表,设置一个属性列表,不拷贝这些属性值 */ public CopyOptions(Class editable, boolean ignoreNullValue, String... ignoreProperties) { this.propertiesFilter = (f, v) -> true; this.editable = editable; this.ignoreNullValue = ignoreNullValue; this.setIgnoreProperties(ignoreProperties); } /** * 设置限制的类或接口,必须为目标对象的实现接口或父类,用于限制拷贝的属性 * * @param editable 限制的类或接口 * @return CopyOptions */ public CopyOptions setEditable(Class editable) { this.editable = editable; return this; } /** * 设置是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null * * @param ignoreNullVall 是否忽略空值,当源对象的值为null时,true: 忽略而不注入此值,false: 注入null * @return CopyOptions */ public CopyOptions setIgnoreNullValue(boolean ignoreNullVall) { this.ignoreNullValue = ignoreNullVall; return this; } /** * 设置忽略空值,当源对象的值为null时,忽略而不注入此值 * * @return CopyOptions * @since 4.5.7 */ public CopyOptions ignoreNullValue() { return setIgnoreNullValue(true); } /** * 属性过滤器,断言通过的属性才会被复制
* {@link BiPredicate#test(Object, Object)}返回{@code true}则属性通过,{@code false}不通过,抛弃之 * * @param propertiesFilter 属性过滤器 * @return CopyOptions */ public CopyOptions setPropertiesFilter(BiPredicate propertiesFilter) { this.propertiesFilter = propertiesFilter; return this; } /** * 设置忽略的目标对象中属性列表,设置一个属性列表,不拷贝这些属性值 * * @param ignoreProperties 忽略的目标对象中属性列表,设置一个属性列表,不拷贝这些属性值 * @return CopyOptions */ public CopyOptions setIgnoreProperties(String... ignoreProperties) { return setPropertiesFilter((field, o) -> false == ArrayUtil.contains(ignoreProperties, field.getName())); } /** * 设置忽略的目标对象中属性列表,设置一个属性列表,不拷贝这些属性值,Lambda方式 * * @param

参数类型 * @param 返回值类型 * @param funcs 忽略的目标对象中属性列表,设置一个属性列表,不拷贝这些属性值 * @return CopyOptions * @since 5.8.0 */ @SuppressWarnings("unchecked") public CopyOptions setIgnoreProperties(Func1... funcs) { final Set ignoreProperties = ArrayUtil.mapToSet(funcs, LambdaUtil::getFieldName); return setPropertiesFilter((field, o) -> false == ignoreProperties.contains(field.getName())); } /** * 设置是否忽略字段的注入错误 * * @param ignoreError 是否忽略注入错误 * @return CopyOptions */ public CopyOptions setIgnoreError(boolean ignoreError) { this.ignoreError = ignoreError; return this; } /** * 设置忽略字段的注入错误 * * @return CopyOptions * @since 4.5.7 */ public CopyOptions ignoreError() { return setIgnoreError(true); } /** * 设置是否忽略字段的大小写 * * @param ignoreCase 是否忽略大小写 * @return CopyOptions */ public CopyOptions setIgnoreCase(boolean ignoreCase) { this.ignoreCase = ignoreCase; return this; } /** * 设置忽略字段的大小写 * * @return CopyOptions * @since 4.5.7 */ public CopyOptions ignoreCase() { return setIgnoreCase(true); } /** * 设置拷贝属性的字段映射,用于不同的属性之前拷贝做对应表用
* 需要注意的是,当使用ValueProvider作为数据提供者时,这个映射是相反的,即fieldMapping中key为目标Bean的名称,而value是提供者中的key * * @param fieldMapping 拷贝属性的字段映射,用于不同的属性之前拷贝做对应表用 * @return CopyOptions */ public CopyOptions setFieldMapping(Map fieldMapping) { return setFieldNameEditor((key -> fieldMapping.getOrDefault(key, key))); } /** * 设置字段属性编辑器,用于自定义属性转换规则,例如驼峰转下划线等
* 此转换器只针对源端的字段做转换,请确认转换后与目标端字段一致
* 当转换后的字段名为null时忽略这个字段
* 需要注意的是,当使用ValueProvider作为数据提供者时,这个映射是相反的,即fieldMapping中key为目标Bean的名称,而value是提供者中的key * * @param fieldNameEditor 字段属性编辑器,用于自定义属性转换规则,例如驼峰转下划线等 * @return CopyOptions * @since 5.4.2 */ public CopyOptions setFieldNameEditor(Editor fieldNameEditor) { this.fieldNameEditor = fieldNameEditor; return this; } /** * 设置字段属性值编辑器,用于自定义属性值转换规则,例如null转""等
* * @param fieldValueEditor 字段属性值编辑器,用于自定义属性值转换规则,例如null转""等 * @return CopyOptions * @since 5.7.15 */ public CopyOptions setFieldValueEditor(BiFunction fieldValueEditor) { this.fieldValueEditor = fieldValueEditor; return this; } /** * 编辑字段值 * * @param fieldName 字段名 * @param fieldValue 字段值 * @return 编辑后的字段值 * @since 5.7.15 */ protected Object editFieldValue(String fieldName, Object fieldValue) { return (null != this.fieldValueEditor) ? this.fieldValueEditor.apply(fieldName, fieldValue) : fieldValue; } /** * 设置是否支持transient关键字修饰和@Transient注解,如果支持,被修饰的字段或方法对应的字段将被忽略。 * * @param transientSupport 是否支持 * @return this * @since 5.4.2 */ public CopyOptions setTransientSupport(boolean transientSupport) { this.transientSupport = transientSupport; return this; } /** * 设置是否覆盖目标值,如果不覆盖,会先读取目标对象的值,非{@code null}则写,否则忽略。如果覆盖,则不判断直接写 * * @param override 是否覆盖目标值 * @return this * @since 5.7.17 */ public CopyOptions setOverride(boolean override) { this.override = override; return this; } /** * 设置自定义类型转换器,默认使用全局万能转换器转换。 * * @param converter 转换器 * @return this * @since 5.8.0 */ public CopyOptions setConverter(TypeConverter converter) { this.converter = converter; return this; } /** * 使用自定义转换器转换字段值
* 如果自定义转换器为{@code null},则返回原值。 * * @param targetType 目标类型 * @param fieldValue 字段值 * @return 编辑后的字段值 * @since 5.8.0 */ protected Object convertField(Type targetType, Object fieldValue) { return (null != this.converter) ? this.converter.convert(targetType, fieldValue) : fieldValue; } /** * 转换字段名为编辑后的字段名 * * @param fieldName 字段名 * @return 编辑后的字段名 * @since 5.4.2 */ protected String editFieldName(String fieldName) { return (null != this.fieldNameEditor) ? this.fieldNameEditor.edit(fieldName) : fieldName; } /** * 测试是否保留字段,{@code true}保留,{@code false}不保留 * * @param field 字段 * @param value 值 * @return 是否保留 */ protected boolean testPropertyFilter(Field field, Object value) { return null == this.propertiesFilter || this.propertiesFilter.test(field, value); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy