EnumSimpledCoder支持字段名作为setter方法名

This commit is contained in:
redkale
2023-01-29 20:11:17 +08:00
parent 5740d2704a
commit ed5c52cfdc

View File

@@ -1,94 +1,100 @@
/* /*
* To change this license header, choose License Headers in Project Properties. * To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates * To change this template file, choose Tools | Templates
* and open the template in the editor. * and open the template in the editor.
*/ */
package org.redkale.convert.ext; package org.redkale.convert.ext;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.*; import java.util.*;
import org.redkale.convert.*; import org.redkale.convert.*;
import org.redkale.util.RedkaleClassLoader; import org.redkale.util.RedkaleClassLoader;
/** /**
* 枚举 的SimpledCoder实现 * 枚举 的SimpledCoder实现
* *
* <p> * <p>
* 详情见: https://redkale.org * 详情见: https://redkale.org
* *
* @author zhangjx * @author zhangjx
* @param <R> Reader输入的子类型 * @param <R> Reader输入的子类型
* @param <W> Writer输出的子类型 * @param <W> Writer输出的子类型
* @param <E> Enum的子类 * @param <E> Enum的子类
*/ */
public final class EnumSimpledCoder<R extends Reader, W extends Writer, E extends Enum> extends SimpledCoder<R, W, E> { public final class EnumSimpledCoder<R extends Reader, W extends Writer, E extends Enum> extends SimpledCoder<R, W, E> {
private final Encodeable valueEncoder; private final Encodeable valueEncoder;
private final Map<E, Object> enumToValues; private final Map<E, Object> enumToValues;
private final Map<String, E> valueToEnums; private final Map<String, E> valueToEnums;
public EnumSimpledCoder(final ConvertFactory factory, Class<E> type) { public EnumSimpledCoder(final ConvertFactory factory, Class<E> type) {
this.type = type; this.type = type;
ConvertEnumValue cev = type.getAnnotation(ConvertEnumValue.class); ConvertEnumValue cev = type.getAnnotation(ConvertEnumValue.class);
if (cev == null) { if (cev == null) {
this.valueEncoder = null; this.valueEncoder = null;
this.enumToValues = null; this.enumToValues = null;
this.valueToEnums = null; this.valueToEnums = null;
} else { } else {
try { try {
String fieldName = cev.value(); String fieldName = cev.value();
Field field = type.getDeclaredField(fieldName); Field field = type.getDeclaredField(fieldName);
RedkaleClassLoader.putReflectionField(fieldName, field); RedkaleClassLoader.putReflectionField(fieldName, field);
char[] chs = fieldName.toCharArray(); char[] chs = fieldName.toCharArray();
chs[0] = Character.toUpperCase(chs[0]); chs[0] = Character.toUpperCase(chs[0]);
String methodName = "get" + new String(chs); String methodName = "get" + new String(chs);
Method method = type.getMethod(methodName); Method method = null;
RedkaleClassLoader.putReflectionMethod(methodName, method); try {
Map<E, Object> map1 = new HashMap<>(); method = type.getMethod(methodName);
Map<String, E> map2 = new HashMap<>(); } catch (NoSuchMethodException | SecurityException me) {
for (E e : type.getEnumConstants()) { method = type.getMethod(fieldName);
map1.put(e, method.invoke(e)); methodName = fieldName;
map2.put(method.invoke(e).toString(), e); }
} RedkaleClassLoader.putReflectionMethod(methodName, method);
this.valueEncoder = factory.loadEncoder(field.getType()); Map<E, Object> map1 = new HashMap<>();
this.enumToValues = map1; Map<String, E> map2 = new HashMap<>();
this.valueToEnums = map2; for (E e : type.getEnumConstants()) {
} catch (Exception e) { map1.put(e, method.invoke(e));
throw new RuntimeException(e); map2.put(method.invoke(e).toString(), e);
} }
} this.valueEncoder = factory.loadEncoder(field.getType());
} this.enumToValues = map1;
this.valueToEnums = map2;
@Override } catch (Exception e) {
public void convertTo(final W out, final E value) { throw new RuntimeException(e);
if (value == null) { }
out.writeNull(); }
} else if (valueEncoder != null) { }
valueEncoder.convertTo(out, enumToValues.get(value));
} else { @Override
out.writeSmallString(value.toString()); public void convertTo(final W out, final E value) {
} if (value == null) {
} out.writeNull();
} else if (valueEncoder != null) {
@Override valueEncoder.convertTo(out, enumToValues.get(value));
@SuppressWarnings("unchecked") } else {
public E convertFrom(final R in) { out.writeSmallString(value.toString());
String value = in.readSmallString(); }
if (value == null) { }
return null;
} @Override
if (valueToEnums != null) { @SuppressWarnings("unchecked")
return valueToEnums.get(value); public E convertFrom(final R in) {
} else { String value = in.readSmallString();
return (E) Enum.valueOf((Class<E>) type, value); if (value == null) {
} return null;
} }
if (valueToEnums != null) {
@Override return valueToEnums.get(value);
public Class<E> getType() { } else {
return (Class<E>) type; return (E) Enum.valueOf((Class<E>) type, value);
} }
}
}
@Override
public Class<E> getType() {
return (Class<E>) type;
}
}