Skip to content

Commit

Permalink
support export path, improved fastjson 1.x compatible, for issue #2590
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed May 22, 2024
1 parent 457bbb2 commit d106c42
Show file tree
Hide file tree
Showing 6 changed files with 205 additions and 1 deletion.
25 changes: 25 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public abstract class JSONWriter
protected String lastReference;
protected boolean pretty;
protected int indent;
protected Object attachment;

protected JSONWriter(
Context context,
Expand Down Expand Up @@ -251,6 +252,22 @@ public final boolean containsReference(Object value) {
return refs != null && refs.containsKey(value);
}

public final String getPath(Object value) {
Path path;
return refs == null || (path = refs.get(value)) == null
? "$"
: path.toString();
}

/**
* If ReferenceDetection has been set, returns the path of the current object, otherwise returns null
* @since 2.0.51
* @return the path of the current object
*/
public String getPath() {
return path == null ? null : path.toString();
}

public final boolean removeReference(Object value) {
return this.refs != null && this.refs.remove(value) != null;
}
Expand Down Expand Up @@ -2505,4 +2522,12 @@ public final void writeReference(Object object) {
writeReference(path.toString());
}
}

public Object getAttachment() {
return attachment;
}

public void setAttachment(Object attachment) {
this.attachment = attachment;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.alibaba.fastjson2.issues_2500;

import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.SerialContext;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.filter.PropertyPreFilter;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Issue2590 {
@Test
public void test() {
Bean bean = new Bean();
bean.item0 = new Item(101);
bean.item1 = new Item(102);
bean.item2 = new Item(103);

FilterDemo filter = new FilterDemo();
String json = JSON.toJSONString(bean, filter, JSONWriter.Feature.ReferenceDetection);
assertEquals("{\"item0\":{\"id\":101},\"item1\":{\"id\":102},\"item2\":{}}", json);
}

public static class FilterDemo
implements PropertyPreFilter {
@Override
public boolean process(JSONWriter writer, Object source, String name) {
String parentPath = writer.getPath();
if (parentPath.startsWith("$.item2")) {
return false;
}
return true;
}
}

@Test
public void test1() {
Bean bean = new Bean();
bean.item0 = new Item(101);
bean.item1 = new Item(102);
bean.item2 = new Item(103);

FilterDemo1 filter = new FilterDemo1();
String json = com.alibaba.fastjson.JSON.toJSONString(bean, filter);
assertEquals("{\"item0\":{\"id\":101},\"item1\":{\"id\":102},\"item2\":{}}", json);
}

public static class FilterDemo1
implements com.alibaba.fastjson.serializer.PropertyPreFilter {
@Override
public boolean apply(JSONSerializer serializer, Object object, String name) {
SerialContext context = serializer.getContext();
if (context.toString().startsWith("$.item2")) {
return false;
}
return true;
}
}

public static class Bean {
public Item item0;
public Item item1;
public Item item2;
}

public static class Item {
public int id;

public Item() {
}

public Item(int id) {
this.id = id;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ public JSONSerializer(SerializeWriter out, SerializeConfig config) {
this.raw = out.raw;
}

public static JSONSerializer getJSONSerializer(JSONWriter writer) {
JSONSerializer serializer = null;
Object attachment = writer.getAttachment();
if (attachment == null) {
attachment = serializer = new JSONSerializer(writer);
writer.setAttachment(attachment);
} else if (attachment instanceof JSONSerializer) {
serializer = (JSONSerializer) attachment;
} else {
serializer = new JSONSerializer(writer);
}
return serializer;
}

public void config(SerializerFeature feature, boolean state) {
if (!state) {
throw new JSONException("not support");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
package com.alibaba.fastjson.serializer;

import com.alibaba.fastjson2.JSONWriter;

public interface PropertyPreFilter
extends SerializeFilter {
extends com.alibaba.fastjson2.filter.PropertyPreFilter, SerializeFilter {
default boolean process(JSONWriter writer, Object source, String name) {
JSONSerializer serializer = JSONSerializer.getJSONSerializer(writer);
serializer.setContext(new SerialContext(writer, serializer.context, source, name, 0, 0));
return apply(serializer, source, name);
}

boolean apply(JSONSerializer serializer, Object object, String name);
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,42 @@
package com.alibaba.fastjson.serializer;

import com.alibaba.fastjson2.JSONWriter;

public class SerialContext {
public final SerialContext parent;
public final Object object;
public final Object fieldName;
public final int features;
JSONWriter jsonWriter;

SerialContext(JSONWriter jsonWriter, SerialContext parent, Object object, Object fieldName, int features, int fieldFeatures) {
this.parent = parent;
this.jsonWriter = jsonWriter;
this.object = object;
this.fieldName = fieldName;
this.features = features;
}

public SerialContext(SerialContext parent, Object object, Object fieldName, int features, int fieldFeatures) {
this.parent = parent;
this.object = object;
this.fieldName = fieldName;
this.features = features;
}

/**
* @deprecated
*/
public String getPath() {
return toString();
}

public String toString() {
String path = null;
if (jsonWriter != null) {
path = jsonWriter.getPath();
}

return path;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.alibaba.fastjson.v2issues;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.PropertyPreFilter;
import com.alibaba.fastjson.serializer.SerialContext;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Issue2590 {
@Test
public void test() {
Bean bean = new Bean();
bean.item0 = new Item(101);
bean.item1 = new Item(102);
bean.item2 = new Item(103);

FilterDemo filter = new FilterDemo();
String json = JSON.toJSONString(bean, filter);
assertEquals("{\"item0\":{\"id\":101},\"item1\":{\"id\":102},\"item2\":{}}", json);
}

public static class FilterDemo
implements PropertyPreFilter {
@Override
public boolean apply(JSONSerializer serializer, Object object, String name) {
SerialContext context = serializer.getContext();
if (context.toString().startsWith("$.item2")) {
return false;
}
return true;
}
}

public static class Bean {
public Item item0;
public Item item1;
public Item item2;
}

public static class Item {
public int id;

public Item() {
}

public Item(int id) {
this.id = id;
}
}
}

0 comments on commit d106c42

Please sign in to comment.