protobuf
This commit is contained in:
@@ -553,6 +553,127 @@ public abstract class ConvertFactory<R extends Reader, W extends Writer> {
|
|||||||
return fname;
|
return fname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String readGetSetFieldName(AccessibleObject element) {
|
||||||
|
if (element instanceof Field) {
|
||||||
|
return ((Field) element).getName();
|
||||||
|
}
|
||||||
|
return readGetSetFieldName((Method) element);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSimpleMemberType(Class declaringClass, Type type, Class clazz) {
|
||||||
|
if (type == String.class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (clazz.isPrimitive()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (clazz.isEnum()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Boolean.class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Byte.class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Short.class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Character.class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Integer.class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Float.class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Long.class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Double.class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == boolean[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == byte[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == short[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == char[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == int[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == float[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == long[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == double[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Boolean[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Byte[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Short[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Character[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Integer[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Float[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Long[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == Double[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (type == String[].class) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (rootFactory().findEncoder(type) != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (declaringClass == clazz) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Collection.class.isAssignableFrom(clazz) && type instanceof ParameterizedType) {
|
||||||
|
Type[] ts = ((ParameterizedType) type).getActualTypeArguments();
|
||||||
|
if (ts.length == 1) {
|
||||||
|
Type t = ts[0];
|
||||||
|
if (t == Boolean.class
|
||||||
|
|| t == Byte.class
|
||||||
|
|| t == Short.class
|
||||||
|
|| t == Character.class
|
||||||
|
|| t == Integer.class
|
||||||
|
|| t == Float.class
|
||||||
|
|| t == Long.class
|
||||||
|
|| t == Double.class
|
||||||
|
|| t == String.class
|
||||||
|
|| rootFactory().findEncoder(t) != null
|
||||||
|
|| ((t instanceof Class) && ((Class) t).isEnum())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
final String getEntityAlias(Class clazz) {
|
final String getEntityAlias(Class clazz) {
|
||||||
if (clazz == String.class) {
|
if (clazz == String.class) {
|
||||||
return "A";
|
return "A";
|
||||||
|
|||||||
@@ -42,121 +42,6 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean checkMemberType(
|
|
||||||
final JsonFactory factory, final Class declaringClass, Type type, Class clazz) {
|
|
||||||
if (type == String.class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (clazz.isPrimitive()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (clazz.isEnum()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Boolean.class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Byte.class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Short.class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Character.class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Integer.class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Float.class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Long.class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Double.class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == boolean[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == byte[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == short[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == char[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == int[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == float[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == long[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == double[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Boolean[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Byte[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Short[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Character[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Integer[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Float[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Long[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == Double[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (type == String[].class) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (factory.rootFactory().findEncoder(type) != null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (declaringClass == clazz) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (Collection.class.isAssignableFrom(clazz) && type instanceof ParameterizedType) {
|
|
||||||
Type[] ts = ((ParameterizedType) type).getActualTypeArguments();
|
|
||||||
if (ts.length == 1) {
|
|
||||||
Type t = ts[0];
|
|
||||||
if (t == Boolean.class
|
|
||||||
|| t == Byte.class
|
|
||||||
|| t == Short.class
|
|
||||||
|| t == Character.class
|
|
||||||
|| t == Integer.class
|
|
||||||
|| t == Float.class
|
|
||||||
|| t == Long.class
|
|
||||||
|| t == Double.class
|
|
||||||
|| t == String.class
|
|
||||||
|| factory.rootFactory().findEncoder(t) != null
|
|
||||||
|| ((t instanceof Class) && ((Class) t).isEnum())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 字段全部是primitive或String类型,且没有泛型的类才能动态生成JsonDynEncoder, 不支持的返回null
|
// 字段全部是primitive或String类型,且没有泛型的类才能动态生成JsonDynEncoder, 不支持的返回null
|
||||||
public static JsonDynEncoder createDyncEncoder(final JsonFactory factory, final Type type) {
|
public static JsonDynEncoder createDyncEncoder(final JsonFactory factory, final Type type) {
|
||||||
if (!(type instanceof Class)) {
|
if (!(type instanceof Class)) {
|
||||||
@@ -239,7 +124,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
if (factory.findFieldCoder(clazz, field.getName()) != null) {
|
if (factory.findFieldCoder(clazz, field.getName()) != null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!(checkMemberType(factory, clazz, field.getGenericType(), field.getType()))) {
|
if (!factory.isSimpleMemberType(clazz, field.getGenericType(), field.getType())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String name = convertFieldName(factory, clazz, field);
|
String name = convertFieldName(factory, clazz, field);
|
||||||
@@ -290,7 +175,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
if (ref != null && ref.fieldFunc() != null) {
|
if (ref != null && ref.fieldFunc() != null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!(checkMemberType(factory, clazz, method.getGenericReturnType(), method.getReturnType()))) {
|
if (!factory.isSimpleMemberType(clazz, method.getGenericReturnType(), method.getReturnType())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String name = convertFieldName(factory, clazz, method);
|
String name = convertFieldName(factory, clazz, method);
|
||||||
@@ -319,8 +204,8 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
return idx1 - idx2;
|
return idx1 - idx2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String n1 = ref1 == null || ref1.name().isEmpty() ? readGetSetFieldName(o1) : ref1.name();
|
String n1 = ref1 == null || ref1.name().isEmpty() ? factory.readGetSetFieldName(o1) : ref1.name();
|
||||||
String n2 = ref2 == null || ref2.name().isEmpty() ? readGetSetFieldName(o2) : ref2.name();
|
String n2 = ref2 == null || ref2.name().isEmpty() ? factory.readGetSetFieldName(o2) : ref2.name();
|
||||||
if (n1 == null && n2 == null) {
|
if (n1 == null && n2 == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -341,11 +226,11 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
|
|
||||||
protected static String convertFieldName(final JsonFactory factory, Class clazz, AccessibleObject element) {
|
protected static String convertFieldName(final JsonFactory factory, Class clazz, AccessibleObject element) {
|
||||||
ConvertColumnEntry ref = factory.findRef(clazz, element);
|
ConvertColumnEntry ref = factory.findRef(clazz, element);
|
||||||
String name = ref == null || ref.name().isEmpty() ? readGetSetFieldName(element) : ref.name();
|
String name = ref == null || ref.name().isEmpty() ? factory.readGetSetFieldName(element) : ref.name();
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ConvertSmallString readConvertSmallString(AccessibleObject element) {
|
protected static ConvertSmallString readConvertSmallString(JsonFactory factory, AccessibleObject element) {
|
||||||
if (element instanceof Field) {
|
if (element instanceof Field) {
|
||||||
return ((Field) element).getAnnotation(ConvertSmallString.class);
|
return ((Field) element).getAnnotation(ConvertSmallString.class);
|
||||||
}
|
}
|
||||||
@@ -353,7 +238,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
ConvertSmallString small = method.getAnnotation(ConvertSmallString.class);
|
ConvertSmallString small = method.getAnnotation(ConvertSmallString.class);
|
||||||
if (small == null) {
|
if (small == null) {
|
||||||
try {
|
try {
|
||||||
Field f = method.getDeclaringClass().getDeclaredField(readGetSetFieldName(method));
|
Field f = method.getDeclaringClass().getDeclaredField(factory.readGetSetFieldName(method));
|
||||||
if (f != null) {
|
if (f != null) {
|
||||||
small = f.getAnnotation(ConvertSmallString.class);
|
small = f.getAnnotation(ConvertSmallString.class);
|
||||||
}
|
}
|
||||||
@@ -371,26 +256,6 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
return ((Method) element).getReturnType();
|
return ((Method) element).getReturnType();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static String readGetSetFieldName(AccessibleObject element) {
|
|
||||||
if (element instanceof Field) {
|
|
||||||
return ((Field) element).getName();
|
|
||||||
}
|
|
||||||
Method method = (Method) element;
|
|
||||||
String fname = method.getName();
|
|
||||||
if (!(fname.startsWith("is") && fname.length() > 2)
|
|
||||||
&& !(fname.startsWith("get") && fname.length() > 3)
|
|
||||||
&& !(fname.startsWith("set") && fname.length() > 3)) {
|
|
||||||
return fname;
|
|
||||||
}
|
|
||||||
fname = fname.substring(fname.startsWith("is") ? 2 : 3);
|
|
||||||
if (fname.length() > 1 && !(fname.charAt(1) >= 'A' && fname.charAt(1) <= 'Z')) {
|
|
||||||
fname = Character.toLowerCase(fname.charAt(0)) + fname.substring(1);
|
|
||||||
} else if (fname.length() == 1) {
|
|
||||||
fname = "" + Character.toLowerCase(fname.charAt(0));
|
|
||||||
}
|
|
||||||
return fname;
|
|
||||||
}
|
|
||||||
|
|
||||||
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> members) {
|
||||||
final ObjectEncoder selfObjEncoder = factory.createObjectEncoder(clazz);
|
final ObjectEncoder selfObjEncoder = factory.createObjectEncoder(clazz);
|
||||||
@@ -415,7 +280,8 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
StringBuilder memberb = new StringBuilder();
|
StringBuilder memberb = new StringBuilder();
|
||||||
for (AccessibleObject element : members) {
|
for (AccessibleObject element : members) {
|
||||||
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
||||||
final String fieldname = ref1 == null || ref1.name().isEmpty() ? readGetSetFieldName(element) : ref1.name();
|
final String fieldname =
|
||||||
|
ref1 == null || ref1.name().isEmpty() ? factory.readGetSetFieldName(element) : ref1.name();
|
||||||
memberb.append(fieldname).append(',');
|
memberb.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()) {
|
||||||
@@ -478,7 +344,8 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
int intFieldCount = 0;
|
int intFieldCount = 0;
|
||||||
for (AccessibleObject element : members) {
|
for (AccessibleObject element : members) {
|
||||||
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
||||||
final String fieldname = ref1 == null || ref1.name().isEmpty() ? readGetSetFieldName(element) : ref1.name();
|
final String fieldname =
|
||||||
|
ref1 == null || ref1.name().isEmpty() ? factory.readGetSetFieldName(element) : ref1.name();
|
||||||
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();
|
||||||
fv = cw.visitField(ACC_PROTECTED + ACC_FINAL, fieldname + "CommaFieldBytes", "[B", null, null);
|
fv = cw.visitField(ACC_PROTECTED + ACC_FINAL, fieldname + "CommaFieldBytes", "[B", null, null);
|
||||||
@@ -499,12 +366,12 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
if (fieldType == int.class) {
|
if (fieldType == int.class) {
|
||||||
intFieldCount++;
|
intFieldCount++;
|
||||||
}
|
}
|
||||||
if (fieldType == String.class && membersSize == 1 && readConvertSmallString(element) != null) {
|
if (fieldType == String.class && membersSize == 1 && readConvertSmallString(factory, element) != null) {
|
||||||
onlyOneLatin1FieldObjectFlag = true;
|
onlyOneLatin1FieldObjectFlag = true;
|
||||||
} else if (fieldType != short.class
|
} else if (fieldType != short.class
|
||||||
&& fieldType != int.class
|
&& fieldType != int.class
|
||||||
&& fieldType != long.class
|
&& fieldType != long.class
|
||||||
&& !(fieldType == String.class && readConvertSmallString(element) != null)) {
|
&& !(fieldType == String.class && readConvertSmallString(factory, element) != null)) {
|
||||||
onlyShotIntLongLatin1MoreFieldObjectFlag = false;
|
onlyShotIntLongLatin1MoreFieldObjectFlag = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -525,7 +392,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
for (AccessibleObject element : members) {
|
for (AccessibleObject element : members) {
|
||||||
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
||||||
final String fieldname =
|
final String fieldname =
|
||||||
ref1 == null || ref1.name().isEmpty() ? readGetSetFieldName(element) : ref1.name();
|
ref1 == null || ref1.name().isEmpty() ? factory.readGetSetFieldName(element) : ref1.name();
|
||||||
// xxxFieldBytes
|
// xxxFieldBytes
|
||||||
mv.visitVarInsn(ALOAD, 0);
|
mv.visitVarInsn(ALOAD, 0);
|
||||||
mv.visitLdcInsn("\"" + fieldname + "\":");
|
mv.visitLdcInsn("\"" + fieldname + "\":");
|
||||||
@@ -610,7 +477,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
AccessibleObject element = members.get(elementIndex);
|
AccessibleObject element = members.get(elementIndex);
|
||||||
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
||||||
final String fieldName =
|
final String fieldName =
|
||||||
ref1 == null || ref1.name().isEmpty() ? readGetSetFieldName(element) : ref1.name();
|
ref1 == null || ref1.name().isEmpty() ? factory.readGetSetFieldName(element) : ref1.name();
|
||||||
final Class fieldtype = readGetSetFieldType(element);
|
final Class fieldtype = readGetSetFieldType(element);
|
||||||
|
|
||||||
mv.visitVarInsn(ALOAD, 1);
|
mv.visitVarInsn(ALOAD, 1);
|
||||||
@@ -646,14 +513,14 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
AccessibleObject element1 = members.get(elementIndex);
|
AccessibleObject element1 = members.get(elementIndex);
|
||||||
ConvertColumnEntry ref1 = factory.findRef(clazz, element1);
|
ConvertColumnEntry ref1 = factory.findRef(clazz, element1);
|
||||||
final String fieldName1 =
|
final String fieldName1 =
|
||||||
ref1 == null || ref1.name().isEmpty() ? readGetSetFieldName(element1) : ref1.name();
|
ref1 == null || ref1.name().isEmpty() ? factory.readGetSetFieldName(element1) : ref1.name();
|
||||||
final Class fieldType1 = readGetSetFieldType(element1);
|
final Class fieldType1 = readGetSetFieldType(element1);
|
||||||
|
|
||||||
elementIndex++;
|
elementIndex++;
|
||||||
AccessibleObject element2 = members.get(elementIndex);
|
AccessibleObject element2 = members.get(elementIndex);
|
||||||
ConvertColumnEntry ref2 = factory.findRef(clazz, element2);
|
ConvertColumnEntry ref2 = factory.findRef(clazz, element2);
|
||||||
final String fieldName2 =
|
final String fieldName2 =
|
||||||
ref2 == null || ref2.name().isEmpty() ? readGetSetFieldName(element2) : ref2.name();
|
ref2 == null || ref2.name().isEmpty() ? factory.readGetSetFieldName(element2) : ref2.name();
|
||||||
final Class fieldtype2 = readGetSetFieldType(element2);
|
final Class fieldtype2 = readGetSetFieldType(element2);
|
||||||
|
|
||||||
mv.visitVarInsn(ALOAD, 1);
|
mv.visitVarInsn(ALOAD, 1);
|
||||||
@@ -710,7 +577,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
elementIndex++;
|
elementIndex++;
|
||||||
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
||||||
final String fieldname =
|
final String fieldname =
|
||||||
ref1 == null || ref1.name().isEmpty() ? readGetSetFieldName(element) : ref1.name();
|
ref1 == null || ref1.name().isEmpty() ? factory.readGetSetFieldName(element) : ref1.name();
|
||||||
final Class fieldtype = readGetSetFieldType(element);
|
final Class fieldtype = readGetSetFieldType(element);
|
||||||
|
|
||||||
mv.visitVarInsn(ALOAD, 1);
|
mv.visitVarInsn(ALOAD, 1);
|
||||||
@@ -793,7 +660,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
elementIndex++;
|
elementIndex++;
|
||||||
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
ConvertColumnEntry ref1 = factory.findRef(clazz, element);
|
||||||
final String fieldname =
|
final String fieldname =
|
||||||
ref1 == null || ref1.name().isEmpty() ? readGetSetFieldName(element) : ref1.name();
|
ref1 == null || ref1.name().isEmpty() ? factory.readGetSetFieldName(element) : ref1.name();
|
||||||
final Class fieldtype = readGetSetFieldType(element);
|
final Class fieldtype = readGetSetFieldType(element);
|
||||||
int storeid = ASTORE;
|
int storeid = ASTORE;
|
||||||
int loadid = ALOAD;
|
int loadid = ALOAD;
|
||||||
@@ -972,7 +839,7 @@ public abstract class JsonDynEncoder<T> implements Encodeable<JsonWriter, T> {
|
|||||||
mv.visitVarInsn(loadid, maxLocals);
|
mv.visitVarInsn(loadid, maxLocals);
|
||||||
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeDouble", "(D)V", false);
|
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeDouble", "(D)V", false);
|
||||||
} else if (fieldtype == String.class) {
|
} else if (fieldtype == String.class) {
|
||||||
if (readConvertSmallString(element) == null) {
|
if (readConvertSmallString(factory, element) == null) {
|
||||||
mv.visitVarInsn(ALOAD, 1);
|
mv.visitVarInsn(ALOAD, 1);
|
||||||
mv.visitVarInsn(loadid, maxLocals);
|
mv.visitVarInsn(loadid, maxLocals);
|
||||||
mv.visitMethodInsn(
|
mv.visitMethodInsn(
|
||||||
|
|||||||
250
src/main/java/org/redkale/convert/pb/ProtobufDynEncoder.java
Normal file
250
src/main/java/org/redkale/convert/pb/ProtobufDynEncoder.java
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016-2116 Redkale
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
package org.redkale.convert.pb;
|
||||||
|
|
||||||
|
import java.lang.reflect.AccessibleObject;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.redkale.convert.ConvertColumnEntry;
|
||||||
|
import org.redkale.convert.Encodeable;
|
||||||
|
import org.redkale.convert.ObjectEncoder;
|
||||||
|
import org.redkale.convert.ext.BoolArraySimpledCoder;
|
||||||
|
import org.redkale.convert.ext.BoolSimpledCoder;
|
||||||
|
import org.redkale.convert.ext.ByteArraySimpledCoder;
|
||||||
|
import org.redkale.convert.ext.ByteSimpledCoder;
|
||||||
|
import org.redkale.convert.ext.CharArraySimpledCoder;
|
||||||
|
import org.redkale.convert.ext.CharSimpledCoder;
|
||||||
|
import org.redkale.convert.ext.DoubleArraySimpledCoder;
|
||||||
|
import org.redkale.convert.ext.DoubleSimpledCoder;
|
||||||
|
import org.redkale.convert.ext.FloatArraySimpledCoder;
|
||||||
|
import org.redkale.convert.ext.FloatSimpledCoder;
|
||||||
|
import org.redkale.convert.ext.IntArraySimpledCoder;
|
||||||
|
import org.redkale.convert.ext.IntSimpledCoder;
|
||||||
|
import org.redkale.convert.ext.LongArraySimpledCoder;
|
||||||
|
import org.redkale.convert.ext.LongSimpledCoder;
|
||||||
|
import org.redkale.convert.ext.ShortArraySimpledCoder;
|
||||||
|
import org.redkale.convert.ext.ShortSimpledCoder;
|
||||||
|
import org.redkale.convert.ext.StringArraySimpledCoder;
|
||||||
|
import org.redkale.convert.ext.StringSimpledCoder;
|
||||||
|
import org.redkale.util.RedkaleClassLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简单对象的PROTOBUF序列化操作类
|
||||||
|
*
|
||||||
|
* <p>详情见: https://redkale.org
|
||||||
|
*
|
||||||
|
* @author zhangjx
|
||||||
|
* @since 2.8.0
|
||||||
|
* @param <T> 序列化的数据类型
|
||||||
|
*/
|
||||||
|
public abstract class ProtobufDynEncoder<T> implements Encodeable<ProtobufWriter, T> {
|
||||||
|
|
||||||
|
public abstract void init(final ProtobufFactory factory);
|
||||||
|
|
||||||
|
// 字段全部是primitive或String类型,且没有泛型的类才能动态生成ProtobufDynEncoder, 不支持的返回null
|
||||||
|
public static ProtobufDynEncoder createDyncEncoder(final ProtobufFactory factory, final Type type) {
|
||||||
|
if (!(type instanceof Class)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 发现有自定义的基础数据类型Encoder就不动态生成ProtobufDynEncoder了
|
||||||
|
if (factory.loadEncoder(boolean.class) != BoolSimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(byte.class) != ByteSimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(short.class) != ShortSimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(char.class) != CharSimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(int.class) != IntSimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(float.class) != FloatSimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(long.class) != LongSimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(double.class) != DoubleSimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(String.class) != StringSimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// array
|
||||||
|
if (factory.loadEncoder(boolean[].class) != BoolArraySimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(byte[].class) != ByteArraySimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(short[].class) != ShortArraySimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(char[].class) != CharArraySimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(int[].class) != IntArraySimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(float[].class) != FloatArraySimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(long[].class) != LongArraySimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(double[].class) != DoubleArraySimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (factory.loadEncoder(String[].class) != StringArraySimpledCoder.instance) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Class clazz = (Class) type;
|
||||||
|
List<AccessibleObject> members = null;
|
||||||
|
Set<String> names = new HashSet<>();
|
||||||
|
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 = convertFieldName(factory, 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 = convertFieldName(factory, 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;
|
||||||
|
}
|
||||||
|
Collections.sort(members, (o1, o2) -> {
|
||||||
|
ConvertColumnEntry ref1 = factory.findRef(clazz, o1);
|
||||||
|
ConvertColumnEntry ref2 = factory.findRef(clazz, o2);
|
||||||
|
if ((ref1 != null && ref1.getIndex() > 0) || (ref2 != null && ref2.getIndex() > 0)) {
|
||||||
|
int idx1 = ref1 == null ? Integer.MAX_VALUE / 2 : ref1.getIndex();
|
||||||
|
int idx2 = ref2 == null ? Integer.MAX_VALUE / 2 : ref2.getIndex();
|
||||||
|
if (idx1 != idx2) {
|
||||||
|
return idx1 - idx2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String n1 = ref1 == null || ref1.name().isEmpty() ? factory.readGetSetFieldName(o1) : ref1.name();
|
||||||
|
String n2 = ref2 == null || ref2.name().isEmpty() ? factory.readGetSetFieldName(o2) : ref2.name();
|
||||||
|
if (n1 == null && n2 == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (n1 == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (n2 == null) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return n1.compareTo(n2);
|
||||||
|
});
|
||||||
|
return generateDyncEncoder(factory, clazz, members);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static String convertFieldName(final ProtobufFactory factory, Class clazz, AccessibleObject element) {
|
||||||
|
ConvertColumnEntry ref = factory.findRef(clazz, element);
|
||||||
|
String name = ref == null || ref.name().isEmpty() ? factory.readGetSetFieldName(element) : ref.name();
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static ProtobufDynEncoder generateDyncEncoder(
|
||||||
|
final ProtobufFactory factory, final Class clazz, final List<AccessibleObject> members) {
|
||||||
|
final ObjectEncoder selfObjEncoder = factory.createObjectEncoder(clazz);
|
||||||
|
selfObjEncoder.init(factory);
|
||||||
|
if (selfObjEncoder.getMembers().length != members.size()) {
|
||||||
|
return null; // 存在ignore等定制配置
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -91,6 +91,11 @@ public class ProtobufFactory extends ConvertFactory<ProtobufReader, ProtobufWrit
|
|||||||
return new ProtobufFactory(null, instance.features, instance.enumtostring);
|
return new ProtobufFactory(null, instance.features, instance.enumtostring);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected <E> Encodeable<ProtobufWriter, E> createDyncEncoder(Type type) {
|
||||||
|
return ProtobufDynEncoder.createDyncEncoder(this, type);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SimpledCoder createEnumSimpledCoder(Class enumClass) {
|
protected SimpledCoder createEnumSimpledCoder(Class enumClass) {
|
||||||
return new ProtobufEnumSimpledCoder(enumClass, this.enumtostring);
|
return new ProtobufEnumSimpledCoder(enumClass, this.enumtostring);
|
||||||
|
|||||||
Reference in New Issue
Block a user