com.alibaba.fastjson2.JSONPathCompilerReflect Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fastjson2 Show documentation
Show all versions of fastjson2 Show documentation
Fastjson is a JSON processor (JSON parser + JSON generator) written in Java
package com.alibaba.fastjson2;
import com.alibaba.fastjson2.reader.FieldReader;
import com.alibaba.fastjson2.reader.ObjectReader;
import com.alibaba.fastjson2.writer.FieldWriter;
import com.alibaba.fastjson2.writer.ObjectWriter;
import java.util.function.BiFunction;
public class JSONPathCompilerReflect
implements JSONFactory.JSONPathCompiler {
static final JSONPathCompilerReflect INSTANCE = new JSONPathCompilerReflect();
@Override
public JSONPath compile(
Class objectClass, JSONPath path
) {
if (path instanceof JSONPathSingleName) {
return compileSingleNamePath(objectClass, (JSONPathSingleName) path);
}
if (path instanceof JSONPathTwoSegment) {
JSONPathTwoSegment twoSegmentPath = (JSONPathTwoSegment) path;
JSONPathSegment first = compile(objectClass, path, twoSegmentPath.first, null);
JSONPathSegment segment = compile(objectClass, path, twoSegmentPath.second, first);
if (first != twoSegmentPath.first || segment != twoSegmentPath.second) {
if (first instanceof NameSegmentTyped && segment instanceof NameSegmentTyped) {
return new TwoNameSegmentTypedPath(twoSegmentPath.path, (NameSegmentTyped) first, (NameSegmentTyped) segment);
}
return new JSONPathTwoSegment(twoSegmentPath.path, first, segment);
}
}
return path;
}
protected JSONPath compileSingleNamePath(Class objectClass, JSONPathSingleName path) {
String fieldName = path.name;
ObjectReader objectReader = path.getReaderContext().getObjectReader(objectClass);
FieldReader fieldReader = objectReader.getFieldReader(fieldName);
ObjectWriter objectWriter = path.getWriterContext().getObjectWriter(objectClass);
FieldWriter fieldWriter = objectWriter.getFieldWriter(fieldName);
return new SingleNamePathTyped(path.path, objectClass, objectReader, fieldReader, objectWriter, fieldWriter);
}
protected JSONPathSegment compile(Class objectClass, JSONPath path, JSONPathSegment segment, JSONPathSegment parent) {
if (segment instanceof JSONPathSegmentName) {
JSONPathSegmentName nameSegment = (JSONPathSegmentName) segment;
String fieldName = nameSegment.name;
JSONReader.Context readerContext = path.getReaderContext();
JSONWriter.Context writerContext = path.getWriterContext();
ObjectReader objectReader = null;
FieldReader fieldReader = null;
if (parent == null) {
objectReader = readerContext.getObjectReader(objectClass);
} else if (parent instanceof NameSegmentTyped) {
NameSegmentTyped nameSegmentTyped = (NameSegmentTyped) parent;
if (nameSegmentTyped.fieldReader != null) {
objectReader = readerContext.getObjectReader(nameSegmentTyped.fieldReader.fieldType);
}
}
if (objectReader != null) {
fieldReader = objectReader.getFieldReader(fieldName);
}
ObjectWriter objectWriter = null;
FieldWriter fieldWriter = null;
if (parent == null) {
objectWriter = writerContext.getObjectWriter(objectClass);
} else if (parent instanceof NameSegmentTyped) {
NameSegmentTyped nameSegmentTyped = (NameSegmentTyped) parent;
if (nameSegmentTyped.fieldWriter != null) {
objectWriter = writerContext.getObjectWriter(nameSegmentTyped.fieldWriter.fieldClass);
}
}
if (objectWriter != null) {
fieldWriter = objectWriter.getFieldWriter(fieldName);
}
return new NameSegmentTyped(objectClass, objectReader, fieldReader, objectWriter, fieldWriter, fieldName, nameSegment.nameHashCode);
}
return segment;
}
public static class TwoNameSegmentTypedPath
extends JSONPathTwoSegment {
final NameSegmentTyped first;
final NameSegmentTyped second;
public TwoNameSegmentTypedPath(String path, NameSegmentTyped first, NameSegmentTyped second) {
super(path, first, second);
this.first = first;
this.second = second;
}
@Override
public Object eval(Object root) {
Object firstValue = first.fieldWriter.getFieldValue(root);
if (firstValue == null) {
return null;
}
return second.fieldWriter.getFieldValue(firstValue);
}
@Override
public void set(Object root, Object value) {
Object firstValue = first.fieldWriter.getFieldValue(root);
if (firstValue == null) {
return;
}
second.fieldReader.accept(firstValue, value);
}
@Override
public void setInt(Object root, int value) {
Object firstValue = first.fieldWriter.getFieldValue(root);
if (firstValue == null) {
return;
}
second.fieldReader.accept(firstValue, value);
}
@Override
public void setLong(Object root, long value) {
Object firstValue = first.fieldWriter.getFieldValue(root);
if (firstValue == null) {
return;
}
second.fieldReader.accept(firstValue, value);
}
@Override
public void setCallback(Object root, BiFunction callback) {
Object firstValue = first.fieldWriter.getFieldValue(root);
if (firstValue == null) {
return;
}
Object secondValue = second.fieldWriter.getFieldValue(firstValue);
Object secondValueApply = callback.apply(firstValue, secondValue);
if (secondValueApply == secondValue) {
return;
}
if (second.fieldReader == null) {
throw new UnsupportedOperationException();
}
second.fieldReader.accept(firstValue, secondValueApply);
}
}
public static class NameSegmentTyped
extends JSONPathSegmentName {
final Class objectClass;
final FieldReader fieldReader;
final FieldWriter fieldWriter;
public NameSegmentTyped(
Class objectClass,
ObjectReader objectReader,
FieldReader fieldReader,
ObjectWriter objectWriter,
FieldWriter fieldWriter,
String name,
long nameHashCode
) {
super(name, nameHashCode);
this.objectClass = objectClass;
this.fieldReader = fieldReader;
this.fieldWriter = fieldWriter;
}
@Override
public void eval(JSONPath.Context context) {
if (fieldWriter == null) {
throw new UnsupportedOperationException();
}
Object object = context.parent == null
? context.root
: context.parent.value;
if (object == null) {
return;
}
context.value = fieldWriter.getFieldValue(object);
}
}
public static class SingleNamePathTyped
extends JSONPath {
final Class objectClass;
final ObjectReader objectReader;
final FieldReader fieldReader;
final ObjectWriter objectWriter;
final FieldWriter fieldWriter;
public SingleNamePathTyped(
String path,
Class objectClass,
ObjectReader objectReader,
FieldReader fieldReader,
ObjectWriter objectWriter,
FieldWriter fieldWriter
) {
super(path);
this.objectClass = objectClass;
this.objectReader = objectReader;
this.fieldReader = fieldReader;
this.objectWriter = objectWriter;
this.fieldWriter = fieldWriter;
}
@Override
public JSONPath getParent() {
return null;
}
@Override
public boolean isRef() {
return true;
}
@Override
public boolean contains(Object rootObject) {
return fieldWriter != null
&& fieldWriter.getFieldValue(rootObject) != null;
}
@Override
public Object eval(Object object) {
if (fieldWriter == null) {
throw new UnsupportedOperationException();
}
return fieldWriter.getFieldValue(object);
}
@Override
public Object extract(JSONReader jsonReader) {
throw new UnsupportedOperationException();
}
@Override
public String extractScalar(JSONReader jsonReader) {
throw new UnsupportedOperationException();
}
@Override
public void set(Object rootObject, Object value) {
if (fieldReader == null) {
throw new UnsupportedOperationException();
}
fieldReader.accept(rootObject, value);
}
@Override
public void set(Object rootObject, Object value, JSONReader.Feature... readerFeatures) {
if (fieldReader == null) {
throw new UnsupportedOperationException();
}
fieldReader.accept(rootObject, value);
}
@Override
public void setCallback(Object rootObject, BiFunction callback) {
if (fieldWriter == null) {
throw new UnsupportedOperationException();
}
Object fieldValue = fieldWriter.getFieldValue(rootObject);
Object fieldValueApply = callback.apply(rootObject, fieldValue);
if (fieldValueApply == fieldValue) {
return;
}
if (fieldReader == null) {
throw new UnsupportedOperationException();
}
fieldReader.accept(rootObject, fieldValueApply);
}
@Override
public void setInt(Object rootObject, int value) {
if (fieldReader == null) {
throw new UnsupportedOperationException();
}
fieldReader.accept(rootObject, value);
}
@Override
public void setLong(Object rootObject, long value) {
if (fieldReader == null) {
throw new UnsupportedOperationException();
}
fieldReader.accept(rootObject, value);
}
@Override
public boolean remove(Object rootObject) {
throw new UnsupportedOperationException();
}
}
}