This commit is contained in:
wentch
2015-12-17 16:10:58 +08:00
parent 83bde8de27
commit 78acc10dc9
2 changed files with 64 additions and 18 deletions

View File

@@ -71,6 +71,7 @@ public final class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T
this.creator = factory.loadCreator(clazz); this.creator = factory.loadCreator(clazz);
final Set<DeMember> list = new HashSet(); final Set<DeMember> list = new HashSet();
final ConstructorProperties cps = ObjectEncoder.findConstructorProperties(this.creator);
try { try {
ConvertColumnEntry ref; ConvertColumnEntry ref;
for (final Field field : clazz.getFields()) { for (final Field field : clazz.getFields()) {
@@ -89,7 +90,7 @@ public final class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T
if (!method.getName().startsWith("set")) continue; if (!method.getName().startsWith("set")) continue;
if (method.getParameterTypes().length != 1) continue; if (method.getParameterTypes().length != 1) continue;
if (method.getReturnType() != void.class) continue; if (method.getReturnType() != void.class) continue;
if (reversible) { if (reversible && (cps == null || !ObjectEncoder.contains(cps.value(), ObjectEncoder.readGetSetFieldName(method)))) {
boolean is = method.getParameterTypes()[0] == boolean.class || method.getParameterTypes()[0] == Boolean.class; boolean is = method.getParameterTypes()[0] == boolean.class || method.getParameterTypes()[0] == Boolean.class;
try { try {
clazz.getMethod(method.getName().replaceFirst("set", is ? "is" : "get")); clazz.getMethod(method.getName().replaceFirst("set", is ? "is" : "get"));
@@ -102,10 +103,39 @@ public final class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T
Type t = ObjectEncoder.makeGenericType(method.getGenericParameterTypes()[0], virGenericTypes, realGenericTypes); Type t = ObjectEncoder.makeGenericType(method.getGenericParameterTypes()[0], virGenericTypes, realGenericTypes);
list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, null, null, method), factory.loadDecoder(t))); list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, null, null, method), factory.loadDecoder(t)));
} }
if (cps != null) { //可能存在某些构造函数中的字段名不存在setter方法
for (final String constructorField : cps.value()) {
boolean flag = false;
for (DeMember m : list) {
if (m.attribute.field().equals(constructorField)) {
flag = true;
break;
}
}
if (flag) continue;
//不存在setter方法
try {
Field f = clazz.getDeclaredField(constructorField);
Type t = ObjectEncoder.makeGenericType(f.getGenericType(), virGenericTypes, realGenericTypes);
list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, f, null, null), factory.loadDecoder(t)));
} catch (NoSuchFieldException nsfe) { //不存在field 可能存在getter方法
char[] fs = constructorField.toCharArray();
fs[0] = Character.toUpperCase(fs[0]);
String mn = new String(fs);
Method getter = null;
try {
getter = clazz.getMethod("get" + mn);
} catch (NoSuchMethodException ex) {
getter = clazz.getMethod("is" + mn);
}
Type t = ObjectEncoder.makeGenericType(getter.getGenericParameterTypes()[0], virGenericTypes, realGenericTypes);
list.add(new DeMember(ObjectEncoder.createAttribute(factory, clazz, null, getter, null), factory.loadDecoder(t)));
}
}
}
this.members = list.toArray(new DeMember[list.size()]); this.members = list.toArray(new DeMember[list.size()]);
Arrays.sort(this.members); Arrays.sort(this.members);
try {
ConstructorProperties cps = this.creator.getClass().getConstructor().getAnnotation(ConstructorProperties.class);
if (cps != null) { if (cps != null) {
final String[] fields = cps.value(); final String[] fields = cps.value();
final DeMember<R, T, ?>[] ms = new DeMember[fields.length]; final DeMember<R, T, ?>[] ms = new DeMember[fields.length];
@@ -119,8 +149,6 @@ public final class ObjectDecoder<R extends Reader, T> implements Decodeable<R, T
} }
this.creatorConstructorMembers = ms; this.creatorConstructorMembers = ms;
} }
} catch (Exception e) { //不存在则忽略
}
} catch (Exception ex) { } catch (Exception ex) {
throw new ConvertException(ex); throw new ConvertException(ex);
} }

View File

@@ -5,9 +5,11 @@
*/ */
package org.redkale.convert; package org.redkale.convert;
import java.beans.*;
import org.redkale.util.Attribute; import org.redkale.util.Attribute;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.*; import java.util.*;
import org.redkale.util.*;
/** /**
* *
@@ -92,7 +94,14 @@ public final class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T
return type; return type;
} }
private static String readGetSetFieldName(Method method) { static boolean contains(String[] values, String value) {
for (String str : values) {
if (str.equals(value)) return true;
}
return false;
}
static String readGetSetFieldName(Method method) {
if (method == null) return null; if (method == null) return null;
String fname = method.getName(); String fname = method.getName();
if (!fname.startsWith("is") && !fname.startsWith("get") && !fname.startsWith("set")) return fname; if (!fname.startsWith("is") && !fname.startsWith("get") && !fname.startsWith("set")) return fname;
@@ -105,6 +114,14 @@ public final class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T
return fname; return fname;
} }
static ConstructorProperties findConstructorProperties(Creator creator) {
try {
return creator.getClass().getConstructor().getAnnotation(ConstructorProperties.class);
} catch (Exception e) {
return null;
}
}
static Attribute createAttribute(final Factory factory, Class clazz, final Field field, final Method getter, final Method setter) { static Attribute createAttribute(final Factory factory, Class clazz, final Field field, final Method getter, final Method setter) {
String fieldalias = null; String fieldalias = null;
if (field != null) { // public field if (field != null) { // public field
@@ -146,6 +163,7 @@ public final class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T
if (realGenericTypes != null) { if (realGenericTypes != null) {
// println(type + "," + Arrays.toString(virGenericTypes) + ", " + Arrays.toString(realGenericTypes)); // println(type + "," + Arrays.toString(virGenericTypes) + ", " + Arrays.toString(realGenericTypes));
} }
final ConstructorProperties cps = ObjectEncoder.findConstructorProperties(factory.loadCreator(this.typeClass));
try { try {
ConvertColumnEntry ref; ConvertColumnEntry ref;
for (final Field field : clazz.getFields()) { for (final Field field : clazz.getFields()) {
@@ -165,7 +183,7 @@ public final class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T
if (!method.getName().startsWith("is") && !method.getName().startsWith("get")) continue; if (!method.getName().startsWith("is") && !method.getName().startsWith("get")) continue;
if (method.getParameterTypes().length != 0) continue; if (method.getParameterTypes().length != 0) continue;
if (method.getReturnType() == void.class) continue; if (method.getReturnType() == void.class) continue;
if (reversible) { if (reversible && (cps == null || !contains(cps.value(), readGetSetFieldName(method)))) {
boolean is = method.getName().startsWith("is"); boolean is = method.getName().startsWith("is");
try { try {
clazz.getMethod(method.getName().replaceFirst(is ? "is" : "get", "set"), method.getReturnType()); clazz.getMethod(method.getName().replaceFirst(is ? "is" : "get", "set"), method.getReturnType());