JSONPathTypedMultiNames.java
package com.alibaba.fastjson2;
import com.alibaba.fastjson2.reader.FieldReader;
import com.alibaba.fastjson2.reader.ObjectReaderAdapter;
import com.alibaba.fastjson2.util.TypeUtils;
import com.alibaba.fastjson2.writer.FieldWriter;
import com.alibaba.fastjson2.writer.ObjectWriter;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.time.ZoneId;
import java.util.Map;
class JSONPathTypedMultiNames
extends JSONPathTypedMulti {
final JSONPath prefix;
final JSONPath[] namePaths;
final String[] names;
final FieldReader[] fieldReaders;
final ObjectReaderAdapter<Object[]> objectReader;
JSONPathTypedMultiNames(
JSONPath[] paths,
JSONPath prefix,
JSONPath[] namePaths,
Type[] types,
String[] formats,
long[] pathFeatures,
ZoneId zoneId,
long features
) {
super(paths, types, formats, pathFeatures, zoneId, features);
this.prefix = prefix;
this.namePaths = namePaths;
this.names = new String[paths.length];
for (int i = 0; i < paths.length; i++) {
JSONPathSingleName jsonPathSingleName = (JSONPathSingleName) namePaths[i];
String fieldName = jsonPathSingleName.name;
names[i] = fieldName;
}
long[] fieldReaderFeatures = new long[names.length];
if (pathFeatures != null) {
for (int i = 0; i < pathFeatures.length; i++) {
if ((pathFeatures[i] & Feature.NullOnError.mask) != 0) {
fieldReaderFeatures[i] |= JSONReader.Feature.NullOnError.mask;
}
}
}
Type[] fieldTypes = types.clone();
for (int i = 0; i < fieldTypes.length; i++) {
Type fieldType = fieldTypes[i];
if (fieldType == boolean.class) {
fieldTypes[i] = Boolean.class;
} else if (fieldType == char.class) {
fieldTypes[i] = Character.class;
} else if (fieldType == byte.class) {
fieldTypes[i] = Byte.class;
} else if (fieldType == short.class) {
fieldTypes[i] = Short.class;
} else if (fieldType == int.class) {
fieldTypes[i] = Integer.class;
} else if (fieldType == long.class) {
fieldTypes[i] = Long.class;
} else if (fieldType == float.class) {
fieldTypes[i] = Float.class;
} else if (fieldType == double.class) {
fieldTypes[i] = Double.class;
}
}
final int length = names.length;
objectReader = (ObjectReaderAdapter<Object[]>) JSONFactory.getDefaultObjectReaderProvider()
.createObjectReader(
names,
fieldTypes,
fieldReaderFeatures,
() -> new Object[length],
(o, i, v) -> o[i] = v
);
this.fieldReaders = objectReader.getFieldReaders();
}
@Override
public boolean isRef() {
return true;
}
@Override
public Object eval(Object root) {
Object[] array = new Object[paths.length];
Object object = root;
if (prefix != null) {
object = prefix.eval(root);
}
if (object == null) {
return new Object[paths.length];
}
if (object instanceof Map) {
return objectReader.createInstance((Map) object, 0);
} else {
ObjectWriter objectReader = JSONFactory.defaultObjectWriterProvider
.getObjectWriter(
object.getClass()
);
for (int i = 0; i < names.length; i++) {
FieldWriter fieldWriter = objectReader.getFieldWriter(names[i]);
if (fieldWriter == null) {
continue;
}
Object result = fieldWriter.getFieldValue(object);
Type type = types[i];
if (result != null && result.getClass() != type) {
if (type == Long.class) {
result = TypeUtils.toLong(result);
} else if (type == BigDecimal.class) {
result = TypeUtils.toBigDecimal(result);
} else if (type == String[].class) {
result = TypeUtils.toStringArray(result);
} else {
result = TypeUtils.cast(result, type);
}
}
array[i] = result;
}
}
return array;
}
@Override
public Object extract(JSONReader jsonReader) {
if (prefix != null) {
Object object = jsonReader.readAny();
return eval(object);
}
if (jsonReader.nextIfNull()) {
return new Object[paths.length];
}
if (!jsonReader.nextIfObjectStart()) {
throw new JSONException(jsonReader.info("illegal input, expect '[', but " + jsonReader.current()));
}
return objectReader.readObject(jsonReader, null, null, 0);
}
}