Skip to content

Commit

Permalink
improved JSONPath.remove & set
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Jan 8, 2023
1 parent 57aebf9 commit 369450a
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,46 @@ public JSONPathSegmentName(String name, long nameHashCode) {

@Override
public boolean remove(JSONPath.Context context) {
set(context, null);
Object object = context.parent == null
? context.root
: context.parent.value;

if (object instanceof Map) {
Map map = (Map) object;
map.remove(name);
return context.eval = true;
}

if (object instanceof Collection) {
Collection collection = (Collection) object;
for (Object item : collection) {
if (item == null) {
continue;
}

if (item instanceof Map) {
Map map = (Map) item;
map.remove(name);
continue;
}

ObjectReaderProvider provider = context.path.getReaderContext().getProvider();
ObjectReader objectReader = provider.getObjectReader(item.getClass());
FieldReader fieldReader = objectReader.getFieldReader(nameHashCode);
if (fieldReader != null) {
fieldReader.accept(item, null);
}
}
return context.eval = true;
}

ObjectReaderProvider provider = context.path.getReaderContext().getProvider();
ObjectReader objectReader = provider.getObjectReader(object.getClass());
FieldReader fieldReader = objectReader.getFieldReader(nameHashCode);
if (fieldReader != null) {
fieldReader.accept(object, null);
}

return context.eval = true;
}

Expand Down Expand Up @@ -312,6 +351,40 @@ public void set(JSONPath.Context context, Object value) {
return;
}

if (object instanceof Collection) {
Collection collection = (Collection) object;
for (Object item : collection) {
if (item == null) {
continue;
}

if (item instanceof Map) {
Map map = (Map) item;
Object origin = map.put(name, value);
if (origin != null) {
if ((context.readerFeatures & JSONReader.Feature.DuplicateKeyValueAsArray.mask) != 0) {
if (origin instanceof Collection) {
((Collection) origin).add(value);
map.put(name, value);
} else {
JSONArray array = JSONArray.of(origin, value);
map.put(name, array);
}
}
}
continue;
}

ObjectReaderProvider provider = context.path.getReaderContext().getProvider();
ObjectReader objectReader = provider.getObjectReader(item.getClass());
FieldReader fieldReader = objectReader.getFieldReader(nameHashCode);
if (fieldReader != null) {
fieldReader.accept(item, null);
}
}
return;
}

ObjectReaderProvider provider = context.path.getReaderContext().getProvider();
ObjectReader objectReader = provider.getObjectReader(object.getClass());
FieldReader fieldReader = objectReader.getFieldReader(nameHashCode);
Expand Down
112 changes: 112 additions & 0 deletions core/src/test/java/com/alibaba/fastjson2/issues_1000/Issue1059.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.alibaba.fastjson2.issues_1000;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONPath;
import com.alibaba.fastjson2.JSONWriter;
import org.junit.jupiter.api.Test;

import java.util.List;

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

public class Issue1059 {
@Test
public void testRemove() {
JSONPath path = JSONPath.of("$.a.b");

JSONObject object = JSON.parseObject("{\n" +
" \"a\":{\n" +
" \"b\":\"xxx\"\n" +
" }\n" +
"}");
path.remove(object);
assertEquals("{\"a\":{}}", object.toJSONString(JSONWriter.Feature.WriteNulls));

JSONObject object1 = JSON.parseObject("{\n" +
" \"a\":[\n" +
" {\n" +
" \"b\":\"xxx\"\n" +
" }\n" +
" ]\n" +
"}");
path.remove(object1);
assertEquals("{\"a\":[{}]}", object1.toJSONString(JSONWriter.Feature.WriteNulls));

Bean bean = JSON.parseObject("{\n" +
" \"a\":{\n" +
" \"b\":\"xxx\"\n" +
" }\n" +
"}", Bean.class);
assertEquals("xxx", bean.a.b);
path.remove(bean);
assertNull(bean.a.b);
assertEquals("{\"a\":{}}", JSON.toJSONString(bean));

Bean1 bean1 = JSON.parseObject("{\n" +
" \"a\":[\n" +
" {\n" +
" \"b\":\"xxx\"\n" +
" }\n" +
" ]\n" +
"}", Bean1.class);
path.remove(bean1);
assertEquals("{\"a\":[{}]}", JSON.toJSONString(bean1));
}

@Test
public void testSetNull() {
JSONPath path = JSONPath.of("$.a.b");

JSONObject object = JSON.parseObject("{\n" +
" \"a\":{\n" +
" \"b\":\"xxx\"\n" +
" }\n" +
"}");
path.set(object, null);
assertEquals("{\"a\":{\"b\":null}}", object.toJSONString(JSONWriter.Feature.WriteNulls));

JSONObject object1 = JSON.parseObject("{\n" +
" \"a\":[\n" +
" {\n" +
" \"b\":\"xxx\"\n" +
" }\n" +
" ]\n" +
"}");
path.set(object1, null);
assertEquals("{\"a\":[{\"b\":null}]}", object1.toJSONString(JSONWriter.Feature.WriteNulls));

Bean bean = JSON.parseObject("{\n" +
" \"a\":{\n" +
" \"b\":\"xxx\"\n" +
" }\n" +
"}", Bean.class);
assertEquals("xxx", bean.a.b);
path.set(bean, null);
assertNull(bean.a.b);
assertEquals("{\"a\":{\"b\":null}}", JSON.toJSONString(bean, JSONWriter.Feature.WriteNulls));

Bean1 bean1 = JSON.parseObject("{\n" +
" \"a\":[\n" +
" {\n" +
" \"b\":\"xxx\"\n" +
" }\n" +
" ]\n" +
"}", Bean1.class);
path.set(bean1, null);
assertEquals("{\"a\":[{\"b\":null}]}", JSON.toJSONString(bean1, JSONWriter.Feature.WriteNulls));
}

public static class Bean {
public Item a;
}

public static class Item {
public String b;
}

public static class Bean1 {
public List<Item> a;
}
}

0 comments on commit 369450a

Please sign in to comment.