protobuf
This commit is contained in:
@@ -7,7 +7,6 @@ package org.redkale.convert.json;
|
|||||||
|
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.redkale.asm.AnnotationVisitor;
|
|
||||||
import org.redkale.asm.ClassWriter;
|
import org.redkale.asm.ClassWriter;
|
||||||
import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
|
import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
|
||||||
import org.redkale.asm.FieldVisitor;
|
import org.redkale.asm.FieldVisitor;
|
||||||
@@ -42,30 +41,18 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected static JsonDynEncoder generateDyncEncoder(
|
protected static JsonDynEncoder generateDyncEncoder(
|
||||||
final JsonFactory factory, final Class clazz, final List<AccessibleObject> members) {
|
final JsonFactory factory, final Class clazz, final List<AccessibleObject> elements) {
|
||||||
final ObjectEncoder selfObjEncoder = factory.createObjectEncoder(clazz);
|
final ObjectEncoder selfObjEncoder = factory.createObjectEncoder(clazz);
|
||||||
selfObjEncoder.init(factory);
|
selfObjEncoder.init(factory); // 必须执行,初始化EnMember内部信息
|
||||||
if (selfObjEncoder.getMembers().length != members.size()) {
|
if (selfObjEncoder.getMembers().length != elements.size()) {
|
||||||
return null; // 存在ignore等定制配置
|
return null; // 存在ignore等定制配置
|
||||||
}
|
}
|
||||||
final String supDynName = JsonDynEncoder.class.getName().replace('.', '/');
|
|
||||||
final String valtypeName = clazz.getName().replace('.', '/');
|
|
||||||
final String writerName = JsonWriter.class.getName().replace('.', '/');
|
|
||||||
final String encodeableName = Encodeable.class.getName().replace('.', '/');
|
|
||||||
final String objEncoderName = ObjectEncoder.class.getName().replace('.', '/');
|
|
||||||
final String typeDesc = org.redkale.asm.Type.getDescriptor(Type.class);
|
|
||||||
final String jsonfactoryDesc = org.redkale.asm.Type.getDescriptor(JsonFactory.class);
|
|
||||||
final String jsonwriterDesc = org.redkale.asm.Type.getDescriptor(JsonWriter.class);
|
|
||||||
final String writerDesc = org.redkale.asm.Type.getDescriptor(Writer.class);
|
|
||||||
final String encodeableDesc = org.redkale.asm.Type.getDescriptor(Encodeable.class);
|
|
||||||
final String objEncoderDesc = org.redkale.asm.Type.getDescriptor(ObjectEncoder.class);
|
|
||||||
final String valtypeDesc = org.redkale.asm.Type.getDescriptor(clazz);
|
|
||||||
|
|
||||||
Map<String, AccessibleObject> mixedNames0 = null;
|
Map<String, AccessibleObject> mixedNames0 = null;
|
||||||
StringBuilder memberb = new StringBuilder();
|
StringBuilder elementb = new StringBuilder();
|
||||||
for (AccessibleObject element : members) {
|
for (AccessibleObject element : elements) {
|
||||||
final String fieldName = factory.readConvertFieldName(clazz, element);
|
final String fieldName = factory.readConvertFieldName(clazz, element);
|
||||||
memberb.append(fieldName).append(',');
|
elementb.append(fieldName).append(',');
|
||||||
final Class fieldType = readGetSetFieldType(element);
|
final Class fieldType = readGetSetFieldType(element);
|
||||||
if (fieldType != String.class && !fieldType.isPrimitive()) {
|
if (fieldType != String.class && !fieldType.isPrimitive()) {
|
||||||
if (mixedNames0 == null) {
|
if (mixedNames0 == null) {
|
||||||
@@ -78,7 +65,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||||
final String newDynName = "org/redkaledyn/json/_Dyn" + JsonDynEncoder.class.getSimpleName() + "__"
|
final String newDynName = "org/redkaledyn/json/_Dyn" + JsonDynEncoder.class.getSimpleName() + "__"
|
||||||
+ clazz.getName().replace('.', '_').replace('$', '_') + "_" + factory.getFeatures() + "_"
|
+ clazz.getName().replace('.', '_').replace('$', '_') + "_" + factory.getFeatures() + "_"
|
||||||
+ Utility.md5Hex(memberb.toString()); // tiny必须要加上, 同一个类会有多个字段定制Convert
|
+ Utility.md5Hex(elementb.toString()); // tiny必须要加上, 同一个类会有多个字段定制Convert
|
||||||
try {
|
try {
|
||||||
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
|
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
|
||||||
Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz;
|
Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz;
|
||||||
@@ -104,12 +91,23 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String supDynName = JsonDynEncoder.class.getName().replace('.', '/');
|
||||||
|
final String valtypeName = clazz.getName().replace('.', '/');
|
||||||
|
final String writerName = JsonWriter.class.getName().replace('.', '/');
|
||||||
|
final String encodeableName = Encodeable.class.getName().replace('.', '/');
|
||||||
|
final String objEncoderName = ObjectEncoder.class.getName().replace('.', '/');
|
||||||
|
final String typeDesc = org.redkale.asm.Type.getDescriptor(Type.class);
|
||||||
|
final String jsonfactoryDesc = org.redkale.asm.Type.getDescriptor(JsonFactory.class);
|
||||||
|
final String jsonwriterDesc = org.redkale.asm.Type.getDescriptor(JsonWriter.class);
|
||||||
|
final String writerDesc = org.redkale.asm.Type.getDescriptor(Writer.class);
|
||||||
|
final String encodeableDesc = org.redkale.asm.Type.getDescriptor(Encodeable.class);
|
||||||
|
final String objEncoderDesc = org.redkale.asm.Type.getDescriptor(ObjectEncoder.class);
|
||||||
|
final String valtypeDesc = org.redkale.asm.Type.getDescriptor(clazz);
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
|
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
|
||||||
FieldVisitor fv;
|
FieldVisitor fv;
|
||||||
MethodVisitor mv;
|
MethodVisitor mv;
|
||||||
AnnotationVisitor av0;
|
|
||||||
|
|
||||||
cw.visit(
|
cw.visit(
|
||||||
V11,
|
V11,
|
||||||
ACC_PUBLIC + ACC_FINAL + ACC_SUPER,
|
ACC_PUBLIC + ACC_FINAL + ACC_SUPER,
|
||||||
@@ -120,12 +118,12 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
|
|
||||||
fv = cw.visitField(ACC_PROTECTED, "objectEncoderSelf", objEncoderDesc, null, null);
|
fv = cw.visitField(ACC_PROTECTED, "objectEncoderSelf", objEncoderDesc, null, null);
|
||||||
fv.visitEnd();
|
fv.visitEnd();
|
||||||
final int membersSize = members.size();
|
final int membersSize = elements.size();
|
||||||
boolean onlyTwoIntFieldObjectFlag = false; // 只包含两个int字段
|
boolean onlyTwoIntFieldObjectFlag = false; // 只包含两个int字段
|
||||||
boolean onlyOneLatin1FieldObjectFlag = false; // 只包含一个Latin1 String字段
|
boolean onlyOneLatin1FieldObjectFlag = false; // 只包含一个Latin1 String字段
|
||||||
boolean onlyShotIntLongLatin1MoreFieldObjectFlag = true;
|
boolean onlyShotIntLongLatin1MoreFieldObjectFlag = true;
|
||||||
int intFieldCount = 0;
|
int intFieldCount = 0;
|
||||||
for (AccessibleObject element : members) {
|
for (AccessibleObject element : elements) {
|
||||||
final String fieldName = factory.readConvertFieldName(clazz, element);
|
final String fieldName = factory.readConvertFieldName(clazz, element);
|
||||||
fv = cw.visitField(ACC_PROTECTED + ACC_FINAL, fieldName + "FieldBytes", "[B", null, null);
|
fv = cw.visitField(ACC_PROTECTED + ACC_FINAL, fieldName + "FieldBytes", "[B", null, null);
|
||||||
fv.visitEnd();
|
fv.visitEnd();
|
||||||
@@ -170,7 +168,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
mv.visitVarInsn(ALOAD, 2);
|
mv.visitVarInsn(ALOAD, 2);
|
||||||
mv.visitMethodInsn(INVOKESPECIAL, supDynName, "<init>", "(" + jsonfactoryDesc + typeDesc + ")V", false);
|
mv.visitMethodInsn(INVOKESPECIAL, supDynName, "<init>", "(" + jsonfactoryDesc + typeDesc + ")V", false);
|
||||||
|
|
||||||
for (AccessibleObject element : members) {
|
for (AccessibleObject element : elements) {
|
||||||
final String fieldName = factory.readConvertFieldName(clazz, element);
|
final String fieldName = factory.readConvertFieldName(clazz, element);
|
||||||
// xxxFieldBytes
|
// xxxFieldBytes
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
@@ -204,11 +202,11 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
mv.visitFieldInsn(PUTFIELD, newDynName, fieldName + "FirstFieldChars", "[C");
|
mv.visitFieldInsn(PUTFIELD, newDynName, fieldName + "FirstFieldChars", "[C");
|
||||||
}
|
}
|
||||||
mv.visitInsn(RETURN);
|
mv.visitInsn(RETURN);
|
||||||
mv.visitMaxs(1 + members.size(), 1 + members.size());
|
mv.visitMaxs(1 + elements.size(), 1 + elements.size());
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{ // convertTo 方法
|
||||||
mv = (cw.visitMethod(ACC_PUBLIC, "convertTo", "(" + jsonwriterDesc + valtypeDesc + ")V", null, null));
|
mv = (cw.visitMethod(ACC_PUBLIC, "convertTo", "(" + jsonwriterDesc + valtypeDesc + ")V", null, null));
|
||||||
// mv.setDebug(true);
|
// mv.setDebug(true);
|
||||||
{ // if (value == null) { out.writeObjectNull(null); return; }
|
{ // if (value == null) { out.writeObjectNull(null); return; }
|
||||||
@@ -246,14 +244,14 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
int elementIndex = -1;
|
int elementIndex = -1;
|
||||||
final boolean tiny = ConvertFactory.checkTinyFeature(factory.getFeatures());
|
final boolean tiny = ConvertFactory.checkTinyFeature(factory.getFeatures());
|
||||||
final boolean nullable = ConvertFactory.checkNullableFeature(factory.getFeatures());
|
final boolean nullable = ConvertFactory.checkNullableFeature(factory.getFeatures());
|
||||||
final Class firstType = readGetSetFieldType(members.get(0));
|
final Class firstType = readGetSetFieldType(elements.get(0));
|
||||||
final boolean mustHadComma = firstType.isPrimitive()
|
final boolean mustHadComma = firstType.isPrimitive()
|
||||||
&& (firstType != boolean.class || !tiny || nullable); // byte/short/char/int/float/long/double
|
&& (firstType != boolean.class || !tiny || nullable); // byte/short/char/int/float/long/double
|
||||||
|
|
||||||
if (onlyOneLatin1FieldObjectFlag) {
|
if (onlyOneLatin1FieldObjectFlag) {
|
||||||
// out.writeObjectByOnlyOneLatin1FieldValue(messageFirstFieldBytes, value.getMessage());elementIndex++;
|
// out.writeObjectByOnlyOneLatin1FieldValue(messageFirstFieldBytes, value.getMessage());elementIndex++;
|
||||||
elementIndex++;
|
elementIndex++;
|
||||||
AccessibleObject element = members.get(elementIndex);
|
AccessibleObject element = elements.get(elementIndex);
|
||||||
final String fieldName = factory.readConvertFieldName(clazz, element);
|
final String fieldName = factory.readConvertFieldName(clazz, element);
|
||||||
final Class fieldType = readGetSetFieldType(element);
|
final Class fieldType = readGetSetFieldType(element);
|
||||||
|
|
||||||
@@ -287,12 +285,12 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
maxLocals++;
|
maxLocals++;
|
||||||
} else if (onlyTwoIntFieldObjectFlag) {
|
} else if (onlyTwoIntFieldObjectFlag) {
|
||||||
elementIndex++;
|
elementIndex++;
|
||||||
AccessibleObject element1 = members.get(elementIndex);
|
AccessibleObject element1 = elements.get(elementIndex);
|
||||||
final String fieldName1 = factory.readConvertFieldName(clazz, element1);
|
final String fieldName1 = factory.readConvertFieldName(clazz, element1);
|
||||||
final Class fieldType1 = readGetSetFieldType(element1);
|
final Class fieldType1 = readGetSetFieldType(element1);
|
||||||
|
|
||||||
elementIndex++;
|
elementIndex++;
|
||||||
AccessibleObject element2 = members.get(elementIndex);
|
AccessibleObject element2 = elements.get(elementIndex);
|
||||||
final String fieldName2 = factory.readConvertFieldName(clazz, element2);
|
final String fieldName2 = factory.readConvertFieldName(clazz, element2);
|
||||||
final Class fieldtype2 = readGetSetFieldType(element2);
|
final Class fieldtype2 = readGetSetFieldType(element2);
|
||||||
|
|
||||||
@@ -346,7 +344,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
INVOKEVIRTUAL, writerName, "writeObjectByOnlyTwoIntFieldValue", "([B[CI[B[CI)V", false);
|
INVOKEVIRTUAL, writerName, "writeObjectByOnlyTwoIntFieldValue", "([B[CI[B[CI)V", false);
|
||||||
|
|
||||||
} else if (onlyShotIntLongLatin1MoreFieldObjectFlag && mustHadComma) {
|
} else if (onlyShotIntLongLatin1MoreFieldObjectFlag && mustHadComma) {
|
||||||
for (AccessibleObject element : members) {
|
for (AccessibleObject element : elements) {
|
||||||
elementIndex++;
|
elementIndex++;
|
||||||
final String fieldName = factory.readConvertFieldName(clazz, element);
|
final String fieldName = factory.readConvertFieldName(clazz, element);
|
||||||
final Class fieldType = readGetSetFieldType(element);
|
final Class fieldType = readGetSetFieldType(element);
|
||||||
@@ -427,7 +425,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
mv.visitInsn(ICONST_0);
|
mv.visitInsn(ICONST_0);
|
||||||
mv.visitVarInsn(ISTORE, 3);
|
mv.visitVarInsn(ISTORE, 3);
|
||||||
}
|
}
|
||||||
for (AccessibleObject element : members) {
|
for (AccessibleObject element : elements) {
|
||||||
elementIndex++;
|
elementIndex++;
|
||||||
final String fieldName = factory.readConvertFieldName(clazz, element);
|
final String fieldName = factory.readConvertFieldName(clazz, element);
|
||||||
final Class fieldType = readGetSetFieldType(element);
|
final Class fieldType = readGetSetFieldType(element);
|
||||||
@@ -655,7 +653,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
mv.visitMaxs(maxLocals, maxLocals);
|
mv.visitMaxs(maxLocals, maxLocals);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
{
|
{ // convertTo 虚拟方法
|
||||||
mv = (cw.visitMethod(
|
mv = (cw.visitMethod(
|
||||||
ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC,
|
ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC,
|
||||||
"convertTo",
|
"convertTo",
|
||||||
|
|||||||
@@ -7,15 +7,38 @@ package org.redkale.convert.pb;
|
|||||||
import java.lang.reflect.AccessibleObject;
|
import java.lang.reflect.AccessibleObject;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.ArrayList;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.Map;
|
||||||
import java.util.List;
|
import org.redkale.asm.Asms;
|
||||||
import java.util.Set;
|
import org.redkale.asm.ClassWriter;
|
||||||
|
import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
|
||||||
|
import org.redkale.asm.FieldVisitor;
|
||||||
|
import org.redkale.asm.Label;
|
||||||
|
import org.redkale.asm.MethodVisitor;
|
||||||
|
import org.redkale.asm.Opcodes;
|
||||||
|
import static org.redkale.asm.Opcodes.ACC_BRIDGE;
|
||||||
|
import static org.redkale.asm.Opcodes.ACC_FINAL;
|
||||||
|
import static org.redkale.asm.Opcodes.ACC_PROTECTED;
|
||||||
|
import static org.redkale.asm.Opcodes.ACC_PUBLIC;
|
||||||
|
import static org.redkale.asm.Opcodes.ACC_SUPER;
|
||||||
|
import static org.redkale.asm.Opcodes.ACC_SYNTHETIC;
|
||||||
|
import static org.redkale.asm.Opcodes.ALOAD;
|
||||||
|
import static org.redkale.asm.Opcodes.ASTORE;
|
||||||
|
import static org.redkale.asm.Opcodes.CHECKCAST;
|
||||||
|
import static org.redkale.asm.Opcodes.GETFIELD;
|
||||||
|
import static org.redkale.asm.Opcodes.IFNONNULL;
|
||||||
|
import static org.redkale.asm.Opcodes.INVOKESPECIAL;
|
||||||
|
import static org.redkale.asm.Opcodes.INVOKEVIRTUAL;
|
||||||
|
import static org.redkale.asm.Opcodes.POP;
|
||||||
|
import static org.redkale.asm.Opcodes.RETURN;
|
||||||
|
import static org.redkale.asm.Opcodes.V11;
|
||||||
import org.redkale.convert.*;
|
import org.redkale.convert.*;
|
||||||
import org.redkale.convert.ext.*;
|
import org.redkale.convert.ext.*;
|
||||||
|
import org.redkale.util.AnyValue;
|
||||||
import org.redkale.util.RedkaleClassLoader;
|
import org.redkale.util.RedkaleClassLoader;
|
||||||
|
import org.redkale.util.RedkaleException;
|
||||||
|
import org.redkale.util.Utility;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 简单对象的PROTOBUF序列化操作类
|
* 简单对象的PROTOBUF序列化操作类
|
||||||
@@ -26,26 +49,321 @@ import org.redkale.util.RedkaleClassLoader;
|
|||||||
* @since 2.8.0
|
* @since 2.8.0
|
||||||
* @param <T> 序列化的数据类型
|
* @param <T> 序列化的数据类型
|
||||||
*/
|
*/
|
||||||
public abstract class ProtobufDynEncoder<T> implements Encodeable<ProtobufWriter, T> {
|
public abstract class ProtobufDynEncoder<T> extends ProtobufObjectEncoder<T> {
|
||||||
|
|
||||||
protected final Class typeClass;
|
protected final Class typeClass;
|
||||||
|
|
||||||
protected final ObjectEncoder<ProtobufWriter, T> objectEncoder;
|
protected final ObjectEncoder<ProtobufWriter, T> objectEncoderSelf;
|
||||||
|
|
||||||
protected ProtobufDynEncoder(final ProtobufFactory factory, Type type) {
|
// 动态字段: protected SimpledCoder xxxSimpledCoder;
|
||||||
|
|
||||||
|
// 动态字段: protected EnMember xxxEnMember;
|
||||||
|
|
||||||
|
protected ProtobufDynEncoder(final ProtobufFactory factory, Type type, ObjectEncoder objectEncoderSelf) {
|
||||||
|
super((Class) type);
|
||||||
this.typeClass = (Class) type;
|
this.typeClass = (Class) type;
|
||||||
|
this.factory = factory;
|
||||||
|
this.objectEncoderSelf = objectEncoderSelf;
|
||||||
|
this.members = objectEncoderSelf.getMembers();
|
||||||
|
this.inited = true;
|
||||||
factory.register(type, this);
|
factory.register(type, this);
|
||||||
this.objectEncoder = factory.createObjectEncoder(type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ProtobufDynEncoder generateDyncEncoder(
|
@Override
|
||||||
final ProtobufFactory factory, final Class clazz, final List<AccessibleObject> members) {
|
public abstract void convertTo(ProtobufWriter out, T value);
|
||||||
|
|
||||||
|
protected static ProtobufDynEncoder generateDyncEncoder(final ProtobufFactory factory, final Class clazz) {
|
||||||
final ObjectEncoder selfObjEncoder = factory.createObjectEncoder(clazz);
|
final ObjectEncoder selfObjEncoder = factory.createObjectEncoder(clazz);
|
||||||
selfObjEncoder.init(factory);
|
selfObjEncoder.init(factory); // 必须执行,初始化EnMember内部信息
|
||||||
if (selfObjEncoder.getMembers().length != members.size()) {
|
|
||||||
return null; // 存在ignore等定制配置
|
final Map<String, SimpledCoder> simpledCoders = new HashMap<>();
|
||||||
|
final Map<String, EnMember> otherMembers = new HashMap<>();
|
||||||
|
StringBuilder elementb = new StringBuilder();
|
||||||
|
for (EnMember member : selfObjEncoder.getMembers()) {
|
||||||
|
final String fieldName = member.getAttribute().field();
|
||||||
|
final Class fieldClass = member.getAttribute().type();
|
||||||
|
final Type fieldType = member.getAttribute().genericType();
|
||||||
|
elementb.append(fieldName).append(',');
|
||||||
|
if (!ProtobufWriter.isSimpleType(fieldClass)
|
||||||
|
&& !fieldClass.isEnum()
|
||||||
|
&& !ProtobufWriter.supportSimpleCollectionType(fieldType)) {
|
||||||
|
if ((member.getEncoder() instanceof SimpledCoder)) {
|
||||||
|
simpledCoders.put(fieldName, (SimpledCoder) member.getEncoder());
|
||||||
|
} else {
|
||||||
|
otherMembers.put(fieldName, member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||||
|
final String newDynName = "org/redkaledyn/pb/_Dyn" + ProtobufDynEncoder.class.getSimpleName() + "__"
|
||||||
|
+ clazz.getName().replace('.', '_').replace('$', '_') + "_" + factory.getFeatures() + "_"
|
||||||
|
+ Utility.md5Hex(elementb.toString()); // tiny必须要加上, 同一个类会有多个字段定制Convert
|
||||||
|
try {
|
||||||
|
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
|
||||||
|
Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz;
|
||||||
|
ProtobufDynEncoder resultEncoder =
|
||||||
|
(ProtobufDynEncoder) newClazz.getConstructor(ProtobufFactory.class, Type.class, ObjectEncoder.class)
|
||||||
|
.newInstance(factory, clazz, selfObjEncoder);
|
||||||
|
if (!simpledCoders.isEmpty()) {
|
||||||
|
for (Map.Entry<String, SimpledCoder> en : simpledCoders.entrySet()) {
|
||||||
|
Field f = newClazz.getDeclaredField(en.getKey() + "SimpledCoder");
|
||||||
|
f.setAccessible(true);
|
||||||
|
f.set(resultEncoder, en.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!otherMembers.isEmpty()) {
|
||||||
|
for (Map.Entry<String, EnMember> en : otherMembers.entrySet()) {
|
||||||
|
Field f = newClazz.getDeclaredField(en.getKey() + "EnMember");
|
||||||
|
f.setAccessible(true);
|
||||||
|
f.set(resultEncoder, en.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultEncoder;
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
final String supDynName = ProtobufDynEncoder.class.getName().replace('.', '/');
|
||||||
|
final String valtypeName = clazz.getName().replace('.', '/');
|
||||||
|
final String pbwriterName = ProtobufWriter.class.getName().replace('.', '/');
|
||||||
|
final String typeDesc = org.redkale.asm.Type.getDescriptor(Type.class);
|
||||||
|
final String pbfactoryDesc = org.redkale.asm.Type.getDescriptor(ProtobufFactory.class);
|
||||||
|
final String pbwriterDesc = org.redkale.asm.Type.getDescriptor(ProtobufWriter.class);
|
||||||
|
final String simpledCoderDesc = org.redkale.asm.Type.getDescriptor(SimpledCoder.class);
|
||||||
|
final String enMemberDesc = org.redkale.asm.Type.getDescriptor(EnMember.class);
|
||||||
|
final String objEncoderDesc = org.redkale.asm.Type.getDescriptor(ObjectEncoder.class);
|
||||||
|
final String objectDesc = org.redkale.asm.Type.getDescriptor(Object.class);
|
||||||
|
final String valtypeDesc = org.redkale.asm.Type.getDescriptor(clazz);
|
||||||
|
// ------------------------------------------------------------------------------
|
||||||
|
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
|
||||||
|
FieldVisitor fv;
|
||||||
|
MethodVisitor mv;
|
||||||
|
cw.visit(
|
||||||
|
V11,
|
||||||
|
ACC_PUBLIC + ACC_FINAL + ACC_SUPER,
|
||||||
|
newDynName,
|
||||||
|
"L" + supDynName + "<" + valtypeDesc + ">;",
|
||||||
|
supDynName,
|
||||||
|
null);
|
||||||
|
if (!simpledCoders.isEmpty()) {
|
||||||
|
for (String key : simpledCoders.keySet()) {
|
||||||
|
fv = cw.visitField(ACC_PROTECTED, key + "SimpledCoder", simpledCoderDesc, null, null);
|
||||||
|
fv.visitEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!otherMembers.isEmpty()) {
|
||||||
|
for (String key : otherMembers.keySet()) {
|
||||||
|
fv = cw.visitField(ACC_PROTECTED, key + "EnMember", enMemberDesc, null, null);
|
||||||
|
fv.visitEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{ // 构造函数
|
||||||
|
mv = (cw.visitMethod(
|
||||||
|
ACC_PUBLIC, "<init>", "(" + pbfactoryDesc + typeDesc + objEncoderDesc + ")V", null, null));
|
||||||
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
|
mv.visitVarInsn(ALOAD, 1);
|
||||||
|
mv.visitVarInsn(ALOAD, 2);
|
||||||
|
mv.visitVarInsn(ALOAD, 3);
|
||||||
|
mv.visitMethodInsn(
|
||||||
|
INVOKESPECIAL, supDynName, "<init>", "(" + pbfactoryDesc + typeDesc + objEncoderDesc + ")V", false);
|
||||||
|
mv.visitInsn(RETURN);
|
||||||
|
mv.visitMaxs(4, 4);
|
||||||
|
mv.visitEnd();
|
||||||
|
}
|
||||||
|
{ // convertTo 方法
|
||||||
|
mv = (cw.visitMethod(ACC_PUBLIC, "convertTo", "(" + pbwriterDesc + valtypeDesc + ")V", null, null));
|
||||||
|
// if (value == null) return;
|
||||||
|
mv.visitVarInsn(ALOAD, 2); // value
|
||||||
|
Label ifLabel = new Label();
|
||||||
|
mv.visitJumpInsn(IFNONNULL, ifLabel);
|
||||||
|
mv.visitInsn(RETURN);
|
||||||
|
mv.visitLabel(ifLabel);
|
||||||
|
mv.visitLineNumber(33, ifLabel);
|
||||||
|
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
|
||||||
|
// ProtobufWriter out = objectWriter(out0, value);
|
||||||
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
|
mv.visitVarInsn(ALOAD, 1);
|
||||||
|
mv.visitVarInsn(ALOAD, 2);
|
||||||
|
mv.visitMethodInsn(
|
||||||
|
INVOKEVIRTUAL,
|
||||||
|
newDynName,
|
||||||
|
"objectWriter",
|
||||||
|
"(" + pbwriterDesc + objectDesc + ")" + pbwriterDesc,
|
||||||
|
false);
|
||||||
|
mv.visitVarInsn(ASTORE, 3);
|
||||||
|
|
||||||
|
mv.visitVarInsn(ALOAD, 3);
|
||||||
|
mv.visitVarInsn(ALOAD, 2);
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, "writeObjectB", "(Ljava/lang/Object;)I", false);
|
||||||
|
mv.visitInsn(POP);
|
||||||
|
|
||||||
|
for (EnMember member : selfObjEncoder.getMembers()) {
|
||||||
|
final String fieldName = member.getAttribute().field();
|
||||||
|
final Type fieldType = member.getAttribute().genericType();
|
||||||
|
final Class fieldClass = member.getAttribute().type();
|
||||||
|
if (ProtobufWriter.isSimpleType(fieldClass)) {
|
||||||
|
mv.visitVarInsn(ALOAD, 3); // out
|
||||||
|
Asms.visitInsn(mv, member.getTag()); // tag
|
||||||
|
mv.visitVarInsn(ALOAD, 2); // value
|
||||||
|
if (member.getMethod() != null) {
|
||||||
|
String mname = member.getMethod().getName();
|
||||||
|
String mdesc = org.redkale.asm.Type.getMethodDescriptor(member.getMethod());
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, valtypeName, mname, mdesc, false);
|
||||||
|
} else { // field
|
||||||
|
Field field = member.getField();
|
||||||
|
String fname = field.getName();
|
||||||
|
String fdesc = org.redkale.asm.Type.getDescriptor(field.getType());
|
||||||
|
mv.visitFieldInsn(GETFIELD, valtypeName, fname, fdesc);
|
||||||
|
}
|
||||||
|
String fieldDesc = org.redkale.asm.Type.getDescriptor(fieldClass);
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, "writeFieldValue", "(I" + fieldDesc + ")V", false);
|
||||||
|
} else if (fieldClass.isEnum()) {
|
||||||
|
mv.visitVarInsn(ALOAD, 3); // out
|
||||||
|
Asms.visitInsn(mv, member.getTag()); // tag
|
||||||
|
mv.visitVarInsn(ALOAD, 2); // value
|
||||||
|
if (member.getMethod() != null) {
|
||||||
|
String mname = member.getMethod().getName();
|
||||||
|
String mdesc = org.redkale.asm.Type.getMethodDescriptor(member.getMethod());
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, valtypeName, mname, mdesc, false);
|
||||||
|
} else { // field
|
||||||
|
Field field = member.getField();
|
||||||
|
String fname = field.getName();
|
||||||
|
String fdesc = org.redkale.asm.Type.getDescriptor(field.getType());
|
||||||
|
mv.visitFieldInsn(GETFIELD, valtypeName, fname, fdesc);
|
||||||
|
}
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, "writeFieldValue", "(ILjava/lang/Enum;)V", false);
|
||||||
|
} else if (ProtobufWriter.supportSimpleCollectionType(fieldType)) {
|
||||||
|
mv.visitVarInsn(ALOAD, 3); // out
|
||||||
|
Asms.visitInsn(mv, member.getTag()); // tag
|
||||||
|
mv.visitVarInsn(ALOAD, 2); // value
|
||||||
|
if (member.getMethod() != null) {
|
||||||
|
String mname = member.getMethod().getName();
|
||||||
|
String mdesc = org.redkale.asm.Type.getMethodDescriptor(member.getMethod());
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, valtypeName, mname, mdesc, false);
|
||||||
|
} else { // field
|
||||||
|
Field field = member.getField();
|
||||||
|
String fname = field.getName();
|
||||||
|
String fdesc = org.redkale.asm.Type.getDescriptor(field.getType());
|
||||||
|
mv.visitFieldInsn(GETFIELD, valtypeName, fname, fdesc);
|
||||||
|
}
|
||||||
|
Class componentType = ProtobufWriter.getSimpleCollectionComponentType(fieldType);
|
||||||
|
String wmethodName = null;
|
||||||
|
if (componentType == Boolean.class) {
|
||||||
|
wmethodName = "writeFieldBoolsValue";
|
||||||
|
} else if (componentType == Byte.class) {
|
||||||
|
wmethodName = "writeFieldBytesValue";
|
||||||
|
} else if (componentType == Character.class) {
|
||||||
|
wmethodName = "writeFieldCharsValue";
|
||||||
|
} else if (componentType == Short.class) {
|
||||||
|
wmethodName = "writeFieldShortsValue";
|
||||||
|
} else if (componentType == Integer.class) {
|
||||||
|
wmethodName = "writeFieldIntsValue";
|
||||||
|
} else if (componentType == Float.class) {
|
||||||
|
wmethodName = "writeFieldFloatsValue";
|
||||||
|
} else if (componentType == Long.class) {
|
||||||
|
wmethodName = "writeFieldLongsValue";
|
||||||
|
} else if (componentType == Double.class) {
|
||||||
|
wmethodName = "writeFieldDoublesValue";
|
||||||
|
} else if (componentType == String.class) {
|
||||||
|
wmethodName = "writeFieldStringValue";
|
||||||
|
}
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, wmethodName, "(ILjava/util/Collection;)V", false);
|
||||||
|
} else if (simpledCoders.containsKey(fieldName)) {
|
||||||
|
mv.visitVarInsn(ALOAD, 3); // out
|
||||||
|
Asms.visitInsn(mv, member.getTag()); // tag
|
||||||
|
mv.visitVarInsn(ALOAD, 0); // this
|
||||||
|
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "SimpledCoder", simpledCoderDesc);
|
||||||
|
mv.visitVarInsn(ALOAD, 2); // value
|
||||||
|
if (member.getMethod() != null) {
|
||||||
|
String mname = member.getMethod().getName();
|
||||||
|
String mdesc = org.redkale.asm.Type.getMethodDescriptor(member.getMethod());
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, valtypeName, mname, mdesc, false);
|
||||||
|
} else { // field
|
||||||
|
Field field = member.getField();
|
||||||
|
String fname = field.getName();
|
||||||
|
String fdesc = org.redkale.asm.Type.getDescriptor(field.getType());
|
||||||
|
mv.visitFieldInsn(GETFIELD, valtypeName, fname, fdesc);
|
||||||
|
}
|
||||||
|
mv.visitMethodInsn(
|
||||||
|
INVOKEVIRTUAL,
|
||||||
|
pbwriterName,
|
||||||
|
"writeFieldValue",
|
||||||
|
"(I" + simpledCoderDesc + objectDesc + ")V",
|
||||||
|
false);
|
||||||
|
} else {
|
||||||
|
mv.visitVarInsn(ALOAD, 3); // out
|
||||||
|
mv.visitVarInsn(ALOAD, 0); // this
|
||||||
|
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "EnMember", enMemberDesc);
|
||||||
|
mv.visitVarInsn(ALOAD, 2); // value
|
||||||
|
mv.visitMethodInsn(
|
||||||
|
INVOKEVIRTUAL,
|
||||||
|
pbwriterName,
|
||||||
|
"writeObjectField",
|
||||||
|
"(" + enMemberDesc + objectDesc + ")V",
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mv.visitVarInsn(ALOAD, 3); // out
|
||||||
|
mv.visitVarInsn(ALOAD, 2); // value
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, pbwriterName, "writeObjectE", "(Ljava/lang/Object;)V", false);
|
||||||
|
mv.visitInsn(RETURN);
|
||||||
|
mv.visitMaxs(4, 3);
|
||||||
|
mv.visitEnd();
|
||||||
|
}
|
||||||
|
{ // convertTo 虚拟方法
|
||||||
|
mv = (cw.visitMethod(
|
||||||
|
ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC,
|
||||||
|
"convertTo",
|
||||||
|
"(" + pbwriterDesc + "Ljava/lang/Object;)V",
|
||||||
|
null,
|
||||||
|
null));
|
||||||
|
// mv.setDebug(true);
|
||||||
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
|
mv.visitVarInsn(ALOAD, 1);
|
||||||
|
mv.visitVarInsn(ALOAD, 2);
|
||||||
|
mv.visitTypeInsn(CHECKCAST, valtypeName);
|
||||||
|
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "convertTo", "(" + pbwriterDesc + valtypeDesc + ")V", false);
|
||||||
|
mv.visitInsn(RETURN);
|
||||||
|
mv.visitMaxs(3, 3);
|
||||||
|
mv.visitEnd();
|
||||||
|
}
|
||||||
|
cw.visitEnd();
|
||||||
|
|
||||||
|
byte[] bytes = cw.toByteArray();
|
||||||
|
Class<ProtobufDynEncoder> newClazz = (Class<ProtobufDynEncoder>)
|
||||||
|
new ClassLoader(loader) {
|
||||||
|
public final Class<?> loadClass(String name, byte[] b) {
|
||||||
|
return defineClass(name, b, 0, b.length);
|
||||||
|
}
|
||||||
|
}.loadClass(newDynName.replace('/', '.'), bytes);
|
||||||
|
RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz);
|
||||||
|
RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.'));
|
||||||
|
try {
|
||||||
|
ProtobufDynEncoder resultEncoder =
|
||||||
|
(ProtobufDynEncoder) newClazz.getConstructor(ProtobufFactory.class, Type.class, ObjectEncoder.class)
|
||||||
|
.newInstance(factory, clazz, selfObjEncoder);
|
||||||
|
if (!simpledCoders.isEmpty()) {
|
||||||
|
for (Map.Entry<String, SimpledCoder> en : simpledCoders.entrySet()) {
|
||||||
|
Field f = newClazz.getDeclaredField(en.getKey() + "SimpledCoder");
|
||||||
|
f.setAccessible(true);
|
||||||
|
f.set(resultEncoder, en.getValue());
|
||||||
|
RedkaleClassLoader.putReflectionField(newClazz.getName(), f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!otherMembers.isEmpty()) {
|
||||||
|
for (Map.Entry<String, EnMember> en : otherMembers.entrySet()) {
|
||||||
|
Field f = newClazz.getDeclaredField(en.getKey() + "EnMember");
|
||||||
|
f.setAccessible(true);
|
||||||
|
f.set(resultEncoder, en.getValue());
|
||||||
|
RedkaleClassLoader.putReflectionField(newClazz.getName(), f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resultEncoder;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RedkaleException(ex);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 字段全部是primitive或String类型,且没有泛型的类才能动态生成ProtobufDynEncoder, 不支持的返回null
|
// 字段全部是primitive或String类型,且没有泛型的类才能动态生成ProtobufDynEncoder, 不支持的返回null
|
||||||
@@ -53,6 +371,10 @@ public abstract class ProtobufDynEncoder<T> implements Encodeable<ProtobufWriter
|
|||||||
if (!(type instanceof Class)) {
|
if (!(type instanceof Class)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (AnyValue.class.isAssignableFrom((Class) type)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// 发现有自定义的基础数据类型Encoder就不动态生成ProtobufDynEncoder了
|
// 发现有自定义的基础数据类型Encoder就不动态生成ProtobufDynEncoder了
|
||||||
if (factory.loadEncoder(boolean.class) != BoolSimpledCoder.instance) {
|
if (factory.loadEncoder(boolean.class) != BoolSimpledCoder.instance) {
|
||||||
return null;
|
return null;
|
||||||
@@ -106,106 +428,14 @@ public abstract class ProtobufDynEncoder<T> implements Encodeable<ProtobufWriter
|
|||||||
if (factory.loadEncoder(double[].class) != DoubleArraySimpledCoder.instance) {
|
if (factory.loadEncoder(double[].class) != DoubleArraySimpledCoder.instance) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (factory.loadEncoder(String[].class) != StringArraySimpledCoder.instance) {
|
return generateDyncEncoder(factory, (Class) type);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Class clazz = (Class) type;
|
protected static Class readGetSetFieldType(AccessibleObject element) {
|
||||||
List<AccessibleObject> members = null;
|
if (element instanceof Field) {
|
||||||
Set<String> names = new HashSet<>();
|
return ((Field) element).getType();
|
||||||
try {
|
|
||||||
ConvertColumnEntry ref;
|
|
||||||
RedkaleClassLoader.putReflectionPublicFields(clazz.getName());
|
|
||||||
for (final Field field : clazz.getFields()) {
|
|
||||||
if (Modifier.isStatic(field.getModifiers())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (factory.isConvertDisabled(field)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ref = factory.findRef(clazz, field);
|
|
||||||
if (ref != null && ref.ignore()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (factory.findFieldCoder(clazz, field.getName()) != null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!factory.isSimpleMemberType(clazz, field.getGenericType(), field.getType())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String name = factory.readConvertFieldName(clazz, field);
|
|
||||||
if (names.contains(name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
names.add(name);
|
|
||||||
if (members == null) {
|
|
||||||
members = new ArrayList<>();
|
|
||||||
}
|
|
||||||
members.add(field);
|
|
||||||
}
|
|
||||||
RedkaleClassLoader.putReflectionPublicMethods(clazz.getName());
|
|
||||||
for (final Method method : clazz.getMethods()) {
|
|
||||||
if (Modifier.isStatic(method.getModifiers())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (Modifier.isAbstract(method.getModifiers())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (method.isSynthetic()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (method.getName().length() < 3) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (method.getName().equals("getClass")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!(method.getName().startsWith("is") && method.getName().length() > 2)
|
|
||||||
&& !(method.getName().startsWith("get")
|
|
||||||
&& method.getName().length() > 3)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (factory.isConvertDisabled(method)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (method.getParameterTypes().length != 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (method.getReturnType() == void.class) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ref = factory.findRef(clazz, method);
|
|
||||||
if (ref != null && ref.ignore()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ref != null && ref.fieldFunc() != null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!factory.isSimpleMemberType(clazz, method.getGenericReturnType(), method.getReturnType())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String name = factory.readConvertFieldName(clazz, method);
|
|
||||||
if (names.contains(name)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (factory.findFieldCoder(clazz, name) != null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
names.add(name);
|
|
||||||
if (members == null) {
|
|
||||||
members = new ArrayList<>();
|
|
||||||
}
|
|
||||||
members.add(method);
|
|
||||||
}
|
|
||||||
if (members == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
factory.sortFieldIndex(clazz, members);
|
|
||||||
return generateDyncEncoder(factory, clazz, members);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return ((Method) element).getReturnType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -16,19 +16,25 @@ import org.redkale.convert.*;
|
|||||||
public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V> {
|
public class ProtobufMapEncoder<K, V> extends MapEncoder<ProtobufWriter, K, V> {
|
||||||
|
|
||||||
private final boolean enumtostring;
|
private final boolean enumtostring;
|
||||||
|
private final int keyTag;
|
||||||
|
private final int valTag;
|
||||||
|
|
||||||
public ProtobufMapEncoder(ConvertFactory factory, Type type) {
|
public ProtobufMapEncoder(ConvertFactory factory, Type type) {
|
||||||
super(factory, type);
|
super(factory, type);
|
||||||
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
|
this.enumtostring = ((ProtobufFactory) factory).enumtostring;
|
||||||
|
this.keyTag = 1 << 3 | ProtobufFactory.wireType(keyEncoder.getType(), enumtostring);
|
||||||
|
this.valTag = 2 << 3 | ProtobufFactory.wireType(valueEncoder.getType(), enumtostring);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void writeMemberValue(ProtobufWriter out, EnMember member, K key, V value, boolean first) {
|
protected void writeMemberValue(ProtobufWriter out, EnMember member, K key, V value, boolean first) {
|
||||||
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
|
ProtobufWriter tmp = new ProtobufWriter().configFieldFunc(out);
|
||||||
if (member != null) out.writeFieldName(member);
|
if (member != null) {
|
||||||
tmp.writeUInt32(1 << 3 | ProtobufFactory.wireType(keyEncoder.getType(), enumtostring));
|
out.writeFieldName(member);
|
||||||
|
}
|
||||||
|
tmp.writeTag(keyTag);
|
||||||
keyEncoder.convertTo(tmp, key);
|
keyEncoder.convertTo(tmp, key);
|
||||||
tmp.writeUInt32(2 << 3 | ProtobufFactory.wireType(valueEncoder.getType(), enumtostring));
|
tmp.writeTag(valTag);
|
||||||
valueEncoder.convertTo(tmp, value);
|
valueEncoder.convertTo(tmp, value);
|
||||||
out.writeLength(tmp.count());
|
out.writeLength(tmp.count());
|
||||||
out.writeTo(tmp.toArray());
|
out.writeTo(tmp.toArray());
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.redkale.convert.pb;
|
package org.redkale.convert.pb;
|
||||||
|
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -1056,7 +1057,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ClassDepends
|
@ClassDepends
|
||||||
public void writeFieldBoolsValue(int tag, Boolean[] value) {
|
public void writeFieldValue(int tag, Boolean[] value) {
|
||||||
if (value != null && value.length > 0) {
|
if (value != null && value.length > 0) {
|
||||||
writeTag(tag);
|
writeTag(tag);
|
||||||
writeBools(value);
|
writeBools(value);
|
||||||
@@ -1065,7 +1066,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ClassDepends
|
@ClassDepends
|
||||||
public void writeFieldBytesValue(int tag, Byte[] value) {
|
public void writeFieldValue(int tag, Byte[] value) {
|
||||||
if (value != null && value.length > 0) {
|
if (value != null && value.length > 0) {
|
||||||
writeTag(tag);
|
writeTag(tag);
|
||||||
writeBytes(value);
|
writeBytes(value);
|
||||||
@@ -1074,7 +1075,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ClassDepends
|
@ClassDepends
|
||||||
public void writeFieldCharsValue(int tag, Character[] value) {
|
public void writeFieldValue(int tag, Character[] value) {
|
||||||
if (value != null && value.length > 0) {
|
if (value != null && value.length > 0) {
|
||||||
writeTag(tag);
|
writeTag(tag);
|
||||||
writeChars(value);
|
writeChars(value);
|
||||||
@@ -1083,7 +1084,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ClassDepends
|
@ClassDepends
|
||||||
public void writeFieldShortsValue(int tag, Short[] value) {
|
public void writeFieldValue(int tag, Short[] value) {
|
||||||
if (value != null && value.length > 0) {
|
if (value != null && value.length > 0) {
|
||||||
writeTag(tag);
|
writeTag(tag);
|
||||||
writeShorts(value);
|
writeShorts(value);
|
||||||
@@ -1092,7 +1093,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ClassDepends
|
@ClassDepends
|
||||||
public void writeFieldIntsValue(int tag, Integer[] value) {
|
public void writeFieldValue(int tag, Integer[] value) {
|
||||||
if (value != null && value.length > 0) {
|
if (value != null && value.length > 0) {
|
||||||
writeTag(tag);
|
writeTag(tag);
|
||||||
writeInts(value);
|
writeInts(value);
|
||||||
@@ -1101,7 +1102,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ClassDepends
|
@ClassDepends
|
||||||
public void writeFieldFloatsValue(int tag, Float[] value) {
|
public void writeFieldValue(int tag, Float[] value) {
|
||||||
if (value != null && value.length > 0) {
|
if (value != null && value.length > 0) {
|
||||||
writeTag(tag);
|
writeTag(tag);
|
||||||
writeFloats(value);
|
writeFloats(value);
|
||||||
@@ -1110,7 +1111,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ClassDepends
|
@ClassDepends
|
||||||
public void writeFieldLongsValue(int tag, Long[] value) {
|
public void writeFieldValue(int tag, Long[] value) {
|
||||||
if (value != null && value.length > 0) {
|
if (value != null && value.length > 0) {
|
||||||
writeTag(tag);
|
writeTag(tag);
|
||||||
writeLongs(value);
|
writeLongs(value);
|
||||||
@@ -1119,7 +1120,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ClassDepends
|
@ClassDepends
|
||||||
public void writeFieldDoublesValue(int tag, Double[] value) {
|
public void writeFieldValue(int tag, Double[] value) {
|
||||||
if (value != null && value.length > 0) {
|
if (value != null && value.length > 0) {
|
||||||
writeTag(tag);
|
writeTag(tag);
|
||||||
writeDoubles(value);
|
writeDoubles(value);
|
||||||
@@ -1128,9 +1129,8 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ClassDepends
|
@ClassDepends
|
||||||
public void writeFieldStringsValue(int tag, String[] value) {
|
public void writeFieldValue(int tag, String[] value) {
|
||||||
if (value != null && value.length > 0) {
|
if (value != null && value.length > 0) {
|
||||||
writeTag(tag);
|
|
||||||
writeStrings(tag, value);
|
writeStrings(tag, value);
|
||||||
this.comma = true;
|
this.comma = true;
|
||||||
}
|
}
|
||||||
@@ -1211,7 +1211,6 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
@ClassDepends
|
@ClassDepends
|
||||||
public void writeFieldStringsValue(int tag, Collection<String> value) {
|
public void writeFieldStringsValue(int tag, Collection<String> value) {
|
||||||
if (value != null && !value.isEmpty()) {
|
if (value != null && !value.isEmpty()) {
|
||||||
writeTag(tag);
|
|
||||||
writeStrings(tag, value);
|
writeStrings(tag, value);
|
||||||
this.comma = true;
|
this.comma = true;
|
||||||
}
|
}
|
||||||
@@ -1233,7 +1232,7 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
if (enumtostring) {
|
if (enumtostring) {
|
||||||
writeString(value.name());
|
writeString(value.name());
|
||||||
} else {
|
} else {
|
||||||
writeInt(value.ordinal());
|
writeUInt32(value.ordinal());
|
||||||
}
|
}
|
||||||
this.comma = true;
|
this.comma = true;
|
||||||
}
|
}
|
||||||
@@ -1494,6 +1493,70 @@ public class ProtobufWriter extends Writer implements ByteTuple {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isSimpleType(Class fieldClass) {
|
||||||
|
return fieldClass.isPrimitive()
|
||||||
|
|| fieldClass == Boolean.class
|
||||||
|
|| fieldClass == Byte.class
|
||||||
|
|| fieldClass == Character.class
|
||||||
|
|| fieldClass == Short.class
|
||||||
|
|| fieldClass == Integer.class
|
||||||
|
|| fieldClass == Float.class
|
||||||
|
|| fieldClass == Long.class
|
||||||
|
|| fieldClass == Double.class
|
||||||
|
|| fieldClass == String.class
|
||||||
|
|| fieldClass == boolean[].class
|
||||||
|
|| fieldClass == byte[].class
|
||||||
|
|| fieldClass == char[].class
|
||||||
|
|| fieldClass == short[].class
|
||||||
|
|| fieldClass == int[].class
|
||||||
|
|| fieldClass == float[].class
|
||||||
|
|| fieldClass == long[].class
|
||||||
|
|| fieldClass == double[].class
|
||||||
|
|| fieldClass == Boolean[].class
|
||||||
|
|| fieldClass == Byte[].class
|
||||||
|
|| fieldClass == Character[].class
|
||||||
|
|| fieldClass == Short[].class
|
||||||
|
|| fieldClass == Integer[].class
|
||||||
|
|| fieldClass == Float[].class
|
||||||
|
|| fieldClass == Long[].class
|
||||||
|
|| fieldClass == Double[].class
|
||||||
|
|| fieldClass == String[].class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean supportSimpleCollectionType(Type type) {
|
||||||
|
if (!(type instanceof ParameterizedType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ParameterizedType ptype = (ParameterizedType) type;
|
||||||
|
if (!(ptype.getRawType() instanceof Class)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Type[] ptargs = ptype.getActualTypeArguments();
|
||||||
|
if (ptargs == null || ptargs.length != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Class ownerType = (Class) ptype.getRawType();
|
||||||
|
if (!Collection.class.isAssignableFrom(ownerType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Type componentType = ptargs[0];
|
||||||
|
return componentType == Boolean.class
|
||||||
|
|| componentType == Byte.class
|
||||||
|
|| componentType == Character.class
|
||||||
|
|| componentType == Short.class
|
||||||
|
|| componentType == Integer.class
|
||||||
|
|| componentType == Float.class
|
||||||
|
|| componentType == Long.class
|
||||||
|
|| componentType == Double.class
|
||||||
|
|| componentType == String.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class getSimpleCollectionComponentType(Type type) {
|
||||||
|
return supportSimpleCollectionType(type)
|
||||||
|
? (Class) ((ParameterizedType) type).getActualTypeArguments()[0]
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
/** see com.google.protobuf.CodedOutputStream **/
|
/** see com.google.protobuf.CodedOutputStream **/
|
||||||
protected static int computeInt32SizeNoTag(final int value) {
|
protected static int computeInt32SizeNoTag(final int value) {
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
|
|||||||
482
src/test/java/org/redkale/test/convert/pb/UserBean.java
Normal file
482
src/test/java/org/redkale/test/convert/pb/UserBean.java
Normal file
@@ -0,0 +1,482 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2116 Redkale
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
package org.redkale.test.convert.pb;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.redkale.convert.ConvertColumn;
|
||||||
|
import org.redkale.convert.json.JsonConvert;
|
||||||
|
import org.redkale.persistence.Id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
*/
|
||||||
|
public class UserBean {
|
||||||
|
@Id
|
||||||
|
@ConvertColumn(index = 1)
|
||||||
|
private long seqid;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 2)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 3)
|
||||||
|
private String[] remarks;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 4)
|
||||||
|
private byte[] img;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 5)
|
||||||
|
private BigInteger number;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 6)
|
||||||
|
private BigDecimal scale;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 7)
|
||||||
|
private boolean flag;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 8)
|
||||||
|
private short status;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 9)
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 10)
|
||||||
|
private long createTime;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 11)
|
||||||
|
private float point;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 12)
|
||||||
|
private double money;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 13)
|
||||||
|
private byte bit;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 14)
|
||||||
|
private Boolean flag2;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 15)
|
||||||
|
private Short status2;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 16)
|
||||||
|
private Integer id2;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 17)
|
||||||
|
private Long createTime2;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 18)
|
||||||
|
private Float point2;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 19)
|
||||||
|
private Double money2;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 20)
|
||||||
|
private Set<Integer> ids;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 21)
|
||||||
|
public int id3;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 22)
|
||||||
|
public long createTime3;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 23)
|
||||||
|
public float point3;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 24)
|
||||||
|
public double money3;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 25)
|
||||||
|
public byte bit3;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 26)
|
||||||
|
private int[] id4;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 27)
|
||||||
|
private long[] createTime4;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 28)
|
||||||
|
private float[] point4;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 29)
|
||||||
|
private double[] money4;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 30)
|
||||||
|
private byte[] bit4;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 31)
|
||||||
|
private Integer[] id5;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 32)
|
||||||
|
private Long[] createTime5;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 33)
|
||||||
|
private Float[] point5;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 34)
|
||||||
|
private Double[] money5;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 35)
|
||||||
|
private Byte[] bit5;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 36)
|
||||||
|
private List<Integer> id6;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 37)
|
||||||
|
private List<Long> createTime6;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 38)
|
||||||
|
private List<Float> point6;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 39)
|
||||||
|
private List<Double> money6;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 40)
|
||||||
|
private List<Byte> bit6;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 41)
|
||||||
|
private Map<String, String> map;
|
||||||
|
|
||||||
|
@ConvertColumn(index = 42)
|
||||||
|
public UserKind kind;
|
||||||
|
|
||||||
|
public Map<String, String> getMap() {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMap(Map<String, String> map) {
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getId6() {
|
||||||
|
return id6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId6(List<Integer> id6) {
|
||||||
|
this.id6 = id6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Long> getCreateTime6() {
|
||||||
|
return createTime6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime6(List<Long> createTime6) {
|
||||||
|
this.createTime6 = createTime6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Float> getPoint6() {
|
||||||
|
return point6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoint6(List<Float> point6) {
|
||||||
|
this.point6 = point6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Double> getMoney6() {
|
||||||
|
return money6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMoney6(List<Double> money6) {
|
||||||
|
this.money6 = money6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Byte> getBit6() {
|
||||||
|
return bit6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBit6(List<Byte> bit6) {
|
||||||
|
this.bit6 = bit6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId3() {
|
||||||
|
return id3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId3(int id3) {
|
||||||
|
this.id3 = id3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCreateTime3() {
|
||||||
|
return createTime3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime3(long createTime3) {
|
||||||
|
this.createTime3 = createTime3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPoint3() {
|
||||||
|
return point3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoint3(float point3) {
|
||||||
|
this.point3 = point3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMoney3() {
|
||||||
|
return money3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMoney3(double money3) {
|
||||||
|
this.money3 = money3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getBit3() {
|
||||||
|
return bit3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBit3(byte bit3) {
|
||||||
|
this.bit3 = bit3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer[] getId5() {
|
||||||
|
return id5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId5(Integer[] id5) {
|
||||||
|
this.id5 = id5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long[] getCreateTime5() {
|
||||||
|
return createTime5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime5(Long[] createTime5) {
|
||||||
|
this.createTime5 = createTime5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Float[] getPoint5() {
|
||||||
|
return point5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoint5(Float[] point5) {
|
||||||
|
this.point5 = point5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double[] getMoney5() {
|
||||||
|
return money5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMoney5(Double[] money5) {
|
||||||
|
this.money5 = money5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Byte[] getBit5() {
|
||||||
|
return bit5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBit5(Byte[] bit5) {
|
||||||
|
this.bit5 = bit5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getId4() {
|
||||||
|
return id4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId4(int[] id4) {
|
||||||
|
this.id4 = id4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long[] getCreateTime4() {
|
||||||
|
return createTime4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime4(long[] createTime4) {
|
||||||
|
this.createTime4 = createTime4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float[] getPoint4() {
|
||||||
|
return point4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoint4(float[] point4) {
|
||||||
|
this.point4 = point4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double[] getMoney4() {
|
||||||
|
return money4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMoney4(double[] money4) {
|
||||||
|
this.money4 = money4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getBit4() {
|
||||||
|
return bit4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBit4(byte[] bit4) {
|
||||||
|
this.bit4 = bit4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSeqid() {
|
||||||
|
return seqid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSeqid(long seqid) {
|
||||||
|
this.seqid = seqid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserBean setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getRemarks() {
|
||||||
|
return remarks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemarks(String[] remarks) {
|
||||||
|
this.remarks = remarks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Integer> getIds() {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserBean setIds(Set<Integer> ids) {
|
||||||
|
this.ids = ids;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte getBit() {
|
||||||
|
return bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBit(byte bit) {
|
||||||
|
this.bit = bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getImg() {
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImg(byte[] img) {
|
||||||
|
this.img = img;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigInteger getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNumber(BigInteger number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getScale() {
|
||||||
|
return scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScale(BigDecimal scale) {
|
||||||
|
this.scale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFlag() {
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlag(boolean flag) {
|
||||||
|
this.flag = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(short status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCreateTime() {
|
||||||
|
return createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime(long createTime) {
|
||||||
|
this.createTime = createTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPoint() {
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoint(float point) {
|
||||||
|
this.point = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMoney() {
|
||||||
|
return money;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMoney(double money) {
|
||||||
|
this.money = money;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getFlag2() {
|
||||||
|
return flag2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlag2(Boolean flag2) {
|
||||||
|
this.flag2 = flag2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Short getStatus2() {
|
||||||
|
return status2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus2(Short status2) {
|
||||||
|
this.status2 = status2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getId2() {
|
||||||
|
return id2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId2(Integer id2) {
|
||||||
|
this.id2 = id2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getCreateTime2() {
|
||||||
|
return createTime2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreateTime2(Long createTime2) {
|
||||||
|
this.createTime2 = createTime2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Float getPoint2() {
|
||||||
|
return point2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPoint2(Float point2) {
|
||||||
|
this.point2 = point2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getMoney2() {
|
||||||
|
return money2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMoney2(Double money2) {
|
||||||
|
this.money2 = money2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return JsonConvert.root().convertTo(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2116 Redkale
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
package org.redkale.test.convert.pb;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import org.redkale.convert.EnMember;
|
||||||
|
import org.redkale.convert.ObjectEncoder;
|
||||||
|
import org.redkale.convert.SimpledCoder;
|
||||||
|
import org.redkale.convert.pb.ProtobufDynEncoder;
|
||||||
|
import org.redkale.convert.pb.ProtobufFactory;
|
||||||
|
import org.redkale.convert.pb.ProtobufWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
*/
|
||||||
|
public class UserBeanProtoDynEncoder extends ProtobufDynEncoder<UserBean> {
|
||||||
|
protected SimpledCoder numberSimpledCoder;
|
||||||
|
protected SimpledCoder scaleSimpledCoder;
|
||||||
|
protected EnMember mapEnMember;
|
||||||
|
|
||||||
|
public UserBeanProtoDynEncoder(ProtobufFactory factory, Type type, ObjectEncoder objectEncoder) {
|
||||||
|
super(factory, type, objectEncoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void convertTo(ProtobufWriter out0, UserBean value) {
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ProtobufWriter out = objectWriter(out0, value);
|
||||||
|
out.writeObjectB(value);
|
||||||
|
out.writeFieldValue(1, value.getSeqid());
|
||||||
|
out.writeFieldValue(2, value.getName());
|
||||||
|
out.writeFieldValue(3, value.getImg());
|
||||||
|
out.writeFieldValue(4, numberSimpledCoder, value.getNumber());
|
||||||
|
out.writeFieldValue(5, scaleSimpledCoder, value.getScale());
|
||||||
|
out.writeFieldValue(6, value.getBit());
|
||||||
|
|
||||||
|
out.writeFieldValue(7, value.isFlag());
|
||||||
|
out.writeFieldValue(8, value.getStatus());
|
||||||
|
out.writeFieldValue(9, value.getId());
|
||||||
|
out.writeFieldValue(10, value.getCreateTime());
|
||||||
|
out.writeFieldValue(11, value.getPoint());
|
||||||
|
out.writeFieldValue(12, value.getMoney());
|
||||||
|
|
||||||
|
out.writeFieldValue(13, value.getFlag2());
|
||||||
|
out.writeFieldValue(14, value.getStatus2());
|
||||||
|
out.writeFieldValue(15, value.getId2());
|
||||||
|
out.writeFieldValue(16, value.getCreateTime2());
|
||||||
|
out.writeFieldValue(17, value.getPoint2());
|
||||||
|
out.writeFieldValue(18, value.getMoney2());
|
||||||
|
|
||||||
|
out.writeFieldValue(19, value.id3);
|
||||||
|
out.writeFieldValue(20, value.createTime3);
|
||||||
|
out.writeFieldValue(21, value.point3);
|
||||||
|
out.writeFieldValue(22, value.money3);
|
||||||
|
out.writeFieldValue(23, value.bit3);
|
||||||
|
|
||||||
|
out.writeFieldValue(19, value.getId4());
|
||||||
|
out.writeFieldValue(20, value.getCreateTime4());
|
||||||
|
out.writeFieldValue(21, value.getPoint4());
|
||||||
|
out.writeFieldValue(22, value.getMoney4());
|
||||||
|
out.writeFieldValue(23, value.getBit4());
|
||||||
|
|
||||||
|
out.writeFieldValue(19, value.getId5());
|
||||||
|
out.writeFieldValue(20, value.getCreateTime5());
|
||||||
|
out.writeFieldValue(21, value.getPoint5());
|
||||||
|
out.writeFieldValue(22, value.getMoney5());
|
||||||
|
out.writeFieldValue(23, value.getBit5());
|
||||||
|
|
||||||
|
out.writeFieldIntsValue(19, value.getId6());
|
||||||
|
out.writeFieldLongsValue(20, value.getCreateTime6());
|
||||||
|
out.writeFieldFloatsValue(21, value.getPoint6());
|
||||||
|
out.writeFieldDoublesValue(22, value.getMoney6());
|
||||||
|
out.writeFieldBytesValue(23, value.getBit6());
|
||||||
|
|
||||||
|
out.writeFieldValue(100, value.kind);
|
||||||
|
|
||||||
|
out.writeObjectField(mapEnMember, value);
|
||||||
|
out.writeObjectE(out);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
src/test/java/org/redkale/test/convert/pb/UserDynTest.java
Normal file
30
src/test/java/org/redkale/test/convert/pb/UserDynTest.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2116 Redkale
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
package org.redkale.test.convert.pb;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.redkale.convert.Encodeable;
|
||||||
|
import org.redkale.convert.pb.ProtobufDynEncoder;
|
||||||
|
import org.redkale.convert.pb.ProtobufFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
*/
|
||||||
|
public class UserDynTest {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Throwable {
|
||||||
|
UserDynTest test = new UserDynTest();
|
||||||
|
test.run1();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void run1() throws Exception {
|
||||||
|
ProtobufFactory factory = ProtobufFactory.root();
|
||||||
|
Encodeable encoder = factory.loadEncoder(UserBean.class);
|
||||||
|
Assertions.assertTrue(ProtobufDynEncoder.class.isAssignableFrom(encoder.getClass()));
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/test/java/org/redkale/test/convert/pb/UserKind.java
Normal file
15
src/test/java/org/redkale/test/convert/pb/UserKind.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2116 Redkale
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
package org.redkale.test.convert.pb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
*/
|
||||||
|
public enum UserKind {
|
||||||
|
ONE,
|
||||||
|
TWO,
|
||||||
|
THREE;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user