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