Skip to content

Commit

Permalink
refactor use ObjectReaderImplValue
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed May 30, 2022
1 parent 4ddf46c commit 54aab3a
Show file tree
Hide file tree
Showing 9 changed files with 350 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.*;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
Expand Down Expand Up @@ -879,6 +880,11 @@ private void getFieldInfo(FieldInfo fieldInfo, JSONField jsonField) {
fieldInfo.ordinal = ordinal;
}

boolean value = jsonField.value();
if (value) {
fieldInfo.features |= FieldInfo.VALUE_MASK;
}

if (jsonField.unwrapped()) {
fieldInfo.features |= FieldInfo.UNWRAPPED_MASK;
}
Expand Down Expand Up @@ -1643,10 +1649,18 @@ public ObjectReader getObjectReader(ObjectReaderProvider provider, Type type) {
return MoneySupport.createMonetaryAmountReader();
case "javax.money.NumberValue":
return MoneySupport.createNumberValueReader();
case "java.net.InetAddress":
case "java.net.InetSocketAddress":
case "java.text.SimpleDateFormat":
return new ObjectReaderMisc((Class) type);
case "java.net.InetAddress":
return ObjectReaderImplValue.of((Class<InetAddress>) type, String.class, address -> {
try {
return InetAddress.getByName(address);
} catch (UnknownHostException e) {
throw new JSONException("create address error", e);
}
});
case "java.text.SimpleDateFormat":
return ObjectReaderImplValue.of((Class<SimpleDateFormat>) type, String.class, SimpleDateFormat::new);
case "java.lang.Throwable":
case "java.lang.Exception":
case "java.lang.IllegalStateException":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ protected <T> ObjectReader<T> createObjectReaderWithCreator(
}
}

if (parameters.length == 1 && (fieldInfo.features & FieldInfo.VALUE_MASK) != 0) {
break;
}

String fieldName = fieldInfo.fieldName;
if (fieldName == null || fieldName.isEmpty()) {
if (beanInfo.createParameterNames != null && i < beanInfo.createParameterNames.length) {
Expand Down Expand Up @@ -366,6 +370,48 @@ protected <T> ObjectReader<T> createObjectReaderWithCreator(
}
}

if (parameters.length == 1 && (fieldInfo.features & FieldInfo.VALUE_MASK) != 0) {
Type valueType = beanInfo.creatorConstructor == null
? beanInfo.createMethod.getGenericParameterTypes()[0]
: beanInfo.creatorConstructor.getGenericParameterTypes()[0];
Class valueClass = beanInfo.creatorConstructor == null
? beanInfo.createMethod.getParameterTypes()[0]
: beanInfo.creatorConstructor.getParameterTypes()[0];

JSONSchema jsonSchema = null;
if (fieldInfo.schema != null && !fieldInfo.schema.isEmpty()) {
JSONObject object = JSON.parseObject(fieldInfo.schema);
if (!object.isEmpty()) {
jsonSchema = JSONSchema.of(object, valueClass);
}
}

Object defaultValue = fieldInfo.defaultValue;
if (defaultValue != null && defaultValue.getClass() != valueClass) {
Function typeConvert = JSONFactory
.getDefaultObjectReaderProvider()
.getTypeConvert(defaultValue.getClass(), valueType);
if (typeConvert != null) {
defaultValue = typeConvert.apply(defaultValue);
} else {
throw new JSONException("illegal defaultValue : " + defaultValue + ", class " + valueClass.getName());
}
}

return new ObjectReaderImplValue(
objectClass,
valueType,
valueClass,
fieldInfo.features,
fieldInfo.format,
defaultValue,
jsonSchema,
beanInfo.creatorConstructor,
beanInfo.createMethod,
null
);
}

Function<Map<Long, Object>, Object> function;
if (beanInfo.creatorConstructor != null) {
function = createFunction(beanInfo.creatorConstructor, beanInfo.markerConstructor, paramNames);
Expand Down Expand Up @@ -662,6 +708,53 @@ public <T> ObjectReader<T> createObjectReader(Class<T> objectClass, Type objectT
&& !(Throwable.class.isAssignableFrom(objectClass))
&& defaultConstructor == null
&& matchCount != parameterNames.length) {
if (creatorConstructor.getParameterCount() == 1) {
FieldInfo fieldInfo = new FieldInfo();
for (ObjectReaderModule module : modules) {
ObjectReaderAnnotationProcessor annotationProcessor = module.getAnnotationProcessor();
if (annotationProcessor != null) {
annotationProcessor.getFieldInfo(fieldInfo, objectClass, creatorConstructor, 0, creatorConstructor.getParameters()[0]);
}
}
if ((fieldInfo.features & FieldInfo.VALUE_MASK) != 0) {
Type valueType = creatorConstructor.getGenericParameterTypes()[0];
Class valueClass = creatorConstructor.getParameterTypes()[0];

JSONSchema jsonSchema = null;
if (fieldInfo.schema != null && !fieldInfo.schema.isEmpty()) {
JSONObject object = JSON.parseObject(fieldInfo.schema);
if (!object.isEmpty()) {
jsonSchema = JSONSchema.of(object, valueClass);
}
}

Object defaultValue = fieldInfo.defaultValue;
if (defaultValue != null && defaultValue.getClass() != valueClass) {
Function typeConvert = JSONFactory
.getDefaultObjectReaderProvider()
.getTypeConvert(defaultValue.getClass(), valueType);
if (typeConvert != null) {
defaultValue = typeConvert.apply(defaultValue);
} else {
throw new JSONException("illegal defaultValue : " + defaultValue + ", class " + valueClass.getName());
}
}

return new ObjectReaderImplValue(
objectClass,
valueType,
valueClass,
fieldInfo.features,
fieldInfo.format,
defaultValue,
jsonSchema,
creatorConstructor,
null,
null
);
}
}

Function<Map<Long, Object>, T> function = new ConstructorFunction(alternateConstructors, creatorConstructor, parameterNames);
FieldReader[] paramFieldReaders = createFieldReaders(creatorConstructor.getParameters(), parameterNames);
return new ObjectReaderNoneDefaultConstrutor(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package com.alibaba.fastjson2.reader;

import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.schema.JSONSchema;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.function.Function;

public class ObjectReaderImplValue<I, T>
implements ObjectReader<T> {
final Type valueType;
final Class<I> valueClass;
final long features;
final Constructor<T> constructor;
final Method factoryMethod;
final Function<I, T> function;
final JSONSchema schema;
final Object emptyVariantArgs;
ObjectReader valueReader;

public ObjectReaderImplValue(
Class<T> objectClass,
Type valueType,
Class<I> valueClass,
long features,
String format,
Object defaultValue,
JSONSchema schema,
Constructor<T> constructor,
Method factoryMethod,
Function<I, T> function
) {
this.valueType = valueType;
this.valueClass = valueClass;
this.features = features;
this.schema = schema;
this.constructor = constructor;
this.factoryMethod = factoryMethod;
this.function = function;

if (factoryMethod != null && factoryMethod.getParameterCount() == 2) {
Class<?> varArgType = factoryMethod.getParameterTypes()[1].getComponentType();
emptyVariantArgs = Array.newInstance(varArgType, 0);
} else {
emptyVariantArgs = null;
}
}

@Override
public T readObject(JSONReader jsonReader, long features) {
if (valueReader == null) {
valueReader = jsonReader.getObjectReader(valueType);
}

I value = (I) valueReader.readObject(jsonReader, features | this.features);

if (schema != null) {
schema.validate(value);
}

T object;

if (function != null) {
try {
object = function.apply(value);
} catch (Exception ex) {
throw new JSONException("create object error", ex);
}
} else if (constructor != null) {
try {
object = constructor.newInstance(value);
} catch (Exception ex) {
throw new JSONException("create object error", ex);
}
} else if (factoryMethod != null) {
try {
if (emptyVariantArgs != null) {
object = (T) factoryMethod.invoke(null, value, emptyVariantArgs);
} else {
object = (T) factoryMethod.invoke(null, value);
}
} catch (Exception ex) {
throw new JSONException("create object error", ex);
}
} else {
throw new JSONException("create object error");
}

return object;
}

public static <I, T> ObjectReaderImplValue<I, T> of(Class<T> objectClass, Class<I> valueClass, Method method) {
return new ObjectReaderImplValue(objectClass, valueClass, valueClass, 0L, null, null, null, null, method, null);
}

public static <I, T> ObjectReaderImplValue<I, T> of(Class<T> objectClass, Class<I> valueClass, Function<I, T> function) {
return new ObjectReaderImplValue(objectClass, valueClass, valueClass, 0L, null, null, null, null, null, function);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

public class ObjectReaderMisc
implements ObjectReader {
Expand Down Expand Up @@ -47,20 +46,6 @@ public Object readObject(JSONReader jsonReader, long features) {
return new InetSocketAddress(inetAddress, port);
}

if (objectClass == InetAddress.class) {
String address = jsonReader.readString();
try {
return InetAddress.getByName(address);
} catch (UnknownHostException e) {
throw new JSONException("read InetAddress error", e);
}
}

if (objectClass == java.text.SimpleDateFormat.class) {
String str = jsonReader.readString();
return new java.text.SimpleDateFormat(str);
}

throw new JSONException("not support : " + objectClass.getName());
}
}

This file was deleted.

Loading

0 comments on commit 54aab3a

Please sign in to comment.