Commit 0985590c authored by wenshao's avatar wenshao
Browse files

improved support kotlin data class. #1374

parent f4e746a6
Showing with 95 additions and 18 deletions
+95 -18
......@@ -286,9 +286,10 @@ class JavaBeanInfo {
Type[] getGenericParameterTypes = fieldGenericSupport //
? creatorConstructor.getGenericParameterTypes() //
: parameterTypes;
Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations();
for (int i = 0; i < parameterTypes.length; ++i) {
Annotation[] paramAnnotations = creatorConstructor.getParameterAnnotations()[i];
Annotation[] paramAnnotations = paramAnnotationArrays[i];
JSONField fieldAnnotation = null;
for (Annotation paramAnnotation : paramAnnotations) {
if (paramAnnotation instanceof JSONField) {
......@@ -341,8 +342,9 @@ class JavaBeanInfo {
? factoryMethod.getGenericParameterTypes() //
: parameterTypes;
Annotation[][] paramAnnotationArrays = factoryMethod.getParameterAnnotations();
for (int i = 0; i < parameterTypes.length; ++i) {
Annotation[] paramAnnotations = factoryMethod.getParameterAnnotations()[i];
Annotation[] paramAnnotations = paramAnnotationArrays[i];
JSONField fieldAnnotation = null;
for (Annotation paramAnnotation : paramAnnotations) {
if (paramAnnotation instanceof JSONField) {
......@@ -397,10 +399,11 @@ class JavaBeanInfo {
? creatorConstructor.getGenericParameterTypes() //
: parameterTypes;
Annotation[][] paramAnnotationArrays = creatorConstructor.getParameterAnnotations();
for (int i = 0; i < parameterTypes.length; ++i) {
String paramName = parameters[i];
Annotation[] paramAnnotations = creatorConstructor.getParameterAnnotations()[i];
Annotation[] paramAnnotations = paramAnnotationArrays[i];
JSONField fieldAnnotation = null;
for (Annotation paramAnnotation : paramAnnotations) {
if (paramAnnotation instanceof JSONField) {
......
......@@ -15,25 +15,14 @@
*/
package com.alibaba.fastjson.util;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.AccessControlException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
......@@ -926,6 +915,8 @@ public class TypeUtils {
Map<String, FieldInfo> fieldInfoMap = new LinkedHashMap<String, FieldInfo>();
Map<Class<?>, Field[]> classFieldCache = new HashMap<Class<?>, Field[]>();
boolean kotlin = TypeUtils.isKotlin(clazz);
Field[] declaredFields = clazz.getDeclaredFields();
if (!fieldOnly) {
List<Method> methodList = new ArrayList<Method>();
......@@ -954,6 +945,11 @@ public class TypeUtils {
}
}
// for kotlin
Constructor[] constructors = null;
Annotation[][] paramAnnotationArrays = null;
String[] paramNames = null;
short[] paramNameMapping = null;
for (Method method : methodList) {
String methodName = method.getName();
......@@ -970,6 +966,46 @@ public class TypeUtils {
annotation = getSupperMethodAnnotation(clazz, method);
}
if (annotation == null && kotlin) {
if (constructors == null) {
constructors = clazz.getDeclaredConstructors();
if (constructors.length == 1) {
paramAnnotationArrays = constructors[0].getParameterAnnotations();
paramNames = TypeUtils.getKoltinConstructorParameters(clazz);
if (paramNames != null) {
String[] paramNames_sorted = new String[paramNames.length];
System.arraycopy(paramNames, 0,paramNames_sorted, 0, paramNames.length);
Arrays.sort(paramNames_sorted);
paramNameMapping = new short[paramNames.length];
for (short p = 0; p < paramNames.length; p++) {
int index = Arrays.binarySearch(paramNames_sorted, paramNames[p]);
paramNameMapping[index] = p;
}
paramNames = paramNames_sorted;
}
}
}
if (paramNames != null && paramNameMapping != null && methodName.startsWith("get")) {
String propertyName = decapitalize(methodName.substring(3));
int p = Arrays.binarySearch(paramNames, propertyName);
if (p >= 0) {
short index = paramNameMapping[p];
Annotation[] paramAnnotations = paramAnnotationArrays[index];
if (paramAnnotations != null) {
for (Annotation paramAnnotation : paramAnnotations) {
if (paramAnnotation instanceof JSONField) {
annotation = (JSONField) paramAnnotation;
break;
}
}
}
}
}
}
if (annotation != null) {
if (!annotation.serialize()) {
continue;
......
......@@ -18,7 +18,7 @@ public class DataClassTest extends TestCase {
String json = "{\"aa\":1001,\"bb\":1002}";
Object obj = JSON.parseObject(json, clazz);
assertEquals("{\"a\":1001,\"b\":1002}", JSON.toJSONString(obj));
assertEquals("{\"aa\":1001,\"bb\":1002}", JSON.toJSONString(obj));
}
public static class ExtClassLoader extends ClassLoader {
......
package com.alibaba.json.bvt.kotlin;
import com.alibaba.fastjson.JSON;
import junit.framework.TestCase;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
/**
* Created by wenshao on 06/08/2017.
*/
public class MyStateObjectTest extends TestCase {
public void test_user() throws Exception {
ExtClassLoader classLoader = new ExtClassLoader();
Class clazz = classLoader.loadClass("MyStateObject");
String json = "{\"name\":\"wenshao\",\"age\":99}";
Object obj = JSON.parseObject(json, clazz);
assertEquals("{\"age\":99,\"name\":\"wenshao\"}", JSON.toJSONString(obj));
}
public static class ExtClassLoader extends ClassLoader {
public ExtClassLoader() throws IOException {
super(Thread.currentThread().getContextClassLoader());
{
byte[] bytes;
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("kotlin/MyStateObject.clazz");
bytes = IOUtils.toByteArray(is);
is.close();
super.defineClass("MyStateObject", bytes, 0, bytes.length);
}
}
}
}
File added
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment