增加ConvertEnumValue功能

This commit is contained in:
Redkale
2022-11-16 11:25:15 +08:00
parent 20a545825c
commit a4dd37fff2
4 changed files with 137 additions and 6 deletions

View File

@@ -0,0 +1,28 @@
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package org.redkale.convert;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 用于枚举类序列化的字段名<br>
*
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
@Inherited
@Documented
@Target({TYPE})
@Retention(RUNTIME)
public @interface ConvertEnumValue {
String value();
}

View File

@@ -243,7 +243,7 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
public abstract ConvertFactory createChild(boolean tiny);
protected SimpledCoder createEnumSimpledCoder(Class enumClass) {
return new EnumSimpledCoder(enumClass);
return new EnumSimpledCoder(this, enumClass);
}
protected Type formatObjectType(Type type) {

View File

@@ -5,9 +5,10 @@
*/
package org.redkale.convert.ext;
import org.redkale.convert.Reader;
import org.redkale.convert.SimpledCoder;
import org.redkale.convert.Writer;
import java.lang.reflect.*;
import java.util.*;
import org.redkale.convert.*;
import org.redkale.util.RedkaleClassLoader;
/**
* 枚举 的SimpledCoder实现
@@ -22,14 +23,50 @@ import org.redkale.convert.Writer;
*/
public final class EnumSimpledCoder<R extends Reader, W extends Writer, E extends Enum> extends SimpledCoder<R, W, E> {
public EnumSimpledCoder(Class<E> type) {
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());
}
@@ -40,11 +77,16 @@ public final class EnumSimpledCoder<R extends Reader, W extends Writer, E extend
public E convertFrom(final R in) {
String value = in.readSmallString();
if (value == null) return null;
return (E) Enum.valueOf((Class<E>) type, value);
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;
}
}

View File

@@ -0,0 +1,61 @@
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package org.redkale.test.convert;
import org.redkale.convert.ConvertEnumValue;
import org.junit.jupiter.api.*;
import org.redkale.convert.json.JsonConvert;
/**
*
* @author zhangjx
*/
public class EnumBeanTest {
private boolean main;
public static void main(String[] args) throws Throwable {
EnumBeanTest test = new EnumBeanTest();
test.main = true;
test.run();
}
@Test
public void run() throws Exception {
EnumBean bean = new EnumBean();
bean.v1 = EnumKey.TWO;
bean.v2 = 5;
String expect = "{\"v1\":2,\"v2\":5}";
String json = JsonConvert.root().convertTo(bean);
if (!main) Assertions.assertEquals(expect, json);
System.out.println(json);
EnumBean b = JsonConvert.root().convertFrom(EnumBean.class, json);
String js = JsonConvert.root().convertTo(b);
System.out.println(js);
if (!main) Assertions.assertEquals(expect, js);
}
public static class EnumBean {
public EnumKey v1;
public int v2;
}
@ConvertEnumValue("code")
public static enum EnumKey {
ONE(1), TWO(2);
private final int code;
private EnumKey(int v) {
this.code = v;
}
public int getCode() {
return code;
}
}
}