You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by st...@apache.org on 2017/09/22 21:26:04 UTC
johnzon git commit: JOHNZON-135 support recursive structures
Repository: johnzon
Updated Branches:
refs/heads/master d7a4a2f9d -> 0091f2019
JOHNZON-135 support recursive structures
this is the write part for now.
We still need to support de-serialisation
Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/0091f201
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/0091f201
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/0091f201
Branch: refs/heads/master
Commit: 0091f20199803b9e32bdfe3d696e6109de0ad8b8
Parents: d7a4a2f
Author: Mark Struberg <st...@apache.org>
Authored: Fri Sep 22 23:23:41 2017 +0200
Committer: Mark Struberg <st...@apache.org>
Committed: Fri Sep 22 23:23:41 2017 +0200
----------------------------------------------------------------------
.../johnzon/mapper/MappingGeneratorImpl.java | 62 +++++++++++++++-----
.../johnzon/mapper/CircularExceptionTest.java | 37 ++++++++++++
2 files changed, 85 insertions(+), 14 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/johnzon/blob/0091f201/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java
index 92609c9..f23344c 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingGeneratorImpl.java
@@ -18,6 +18,7 @@
*/
package org.apache.johnzon.mapper;
+import org.apache.johnzon.core.JsonPointerUtil;
import org.apache.johnzon.mapper.internal.AdapterKey;
import javax.json.JsonValue;
@@ -28,12 +29,14 @@ import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Map;
public class MappingGeneratorImpl implements MappingGenerator {
private final MapperConfig config;
private final JsonGenerator generator;
private final Mappings mappings;
+ private Map<Object, String> jsonPointers = new HashMap<>();
MappingGeneratorImpl(MapperConfig config, JsonGenerator jsonGenerator, final Mappings mappings) {
@@ -60,6 +63,7 @@ public class MappingGeneratorImpl implements MappingGenerator {
}
public void doWriteObject(Object object, JsonGenerator generator, boolean writeBody, final Collection<String> ignoredProperties) {
+
try {
if (object instanceof Map) {
if (writeBody) {
@@ -97,7 +101,7 @@ public class MappingGeneratorImpl implements MappingGenerator {
if (writeBody && objectConverter != null) {
objectConverter.writeJson(object, this);
} else {
- doWriteObjectBody(object, ignoredProperties);
+ doWriteObjectBody(object, ignoredProperties, "/");
}
if (writeBody) {
@@ -132,7 +136,7 @@ public class MappingGeneratorImpl implements MappingGenerator {
final boolean map = clazz || primitive || array || collection ? false : Map.class.isAssignableFrom(valueClass);
writeValue(valueClass,
primitive, array, collection, map, itemConverter,
- key == null ? "null" : key.toString(), value, null, null);
+ key == null ? "null" : key.toString(), value, null, null, null);
}
return generator;
}
@@ -224,7 +228,13 @@ public class MappingGeneratorImpl implements MappingGenerator {
}
- private void doWriteObjectBody(final Object object, final Collection<String> ignored) throws IllegalAccessException, InvocationTargetException {
+ private void doWriteObjectBody(final Object object, final Collection<String> ignored, String jsonPointer)
+ throws IllegalAccessException, InvocationTargetException {
+
+ if (jsonPointer != null) {
+ jsonPointers.put(object, jsonPointer);
+ }
+
final Class<?> objectClass = object.getClass();
final Mappings.ClassMapping classMapping = mappings.findOrCreateClassMapping(objectClass);
if (classMapping == null) {
@@ -236,7 +246,7 @@ public class MappingGeneratorImpl implements MappingGenerator {
return;
}
if (classMapping.adapter != null) {
- doWriteObjectBody(classMapping.adapter.to(object), ignored);
+ doWriteObjectBody(classMapping.adapter.to(object), ignored, null);
return;
}
@@ -266,13 +276,23 @@ public class MappingGeneratorImpl implements MappingGenerator {
final Object val = getter.converter == null ? value : getter.converter.from(value);
- writeValue(val.getClass(),
- getter.primitive, getter.array,
- getter.collection, getter.map,
- getter.itemConverter,
- getterEntry.getKey(),
- val, getter.objectConverter,
- getter.ignoreNested);
+ String valJsonPointer = jsonPointers.get(val);
+ if (valJsonPointer != null) {
+ // write the JsonPointer instead
+ generator.write(getterEntry.getKey(), valJsonPointer);
+ } else {
+ writeValue(val.getClass(),
+ getter.primitive,
+ getter.array,
+ getter.collection,
+ getter.map,
+ getter.itemConverter,
+ getterEntry.getKey(),
+ val,
+ getter.objectConverter,
+ getter.ignoreNested,
+ nestJsonPointer(jsonPointer, getterEntry.getKey()));
+ }
}
// @JohnzonAny doesn't respect comparator since it is a map and not purely in the model we append it after and
@@ -285,13 +305,27 @@ public class MappingGeneratorImpl implements MappingGenerator {
}
}
+ private String nestJsonPointer(String jsonPointer, String attribName) {
+ if (jsonPointer == null) {
+ return null;
+ }
+ if (jsonPointer.length() == 1) {
+ // the root element
+ return jsonPointer + attribName;
+ } else {
+ return jsonPointer + "/" + JsonPointerUtil.encode(attribName);
+ }
+ }
+
private void writeValue(final Class<?> type,
final boolean primitive, final boolean array,
final boolean collection, final boolean map,
final Adapter itemConverter,
final String key, final Object value,
final ObjectConverter.Writer objectConverter,
- final Collection<String> ignoredProperties) throws InvocationTargetException, IllegalAccessException {
+ final Collection<String> ignoredProperties,
+ final String jsonPointer)
+ throws InvocationTargetException, IllegalAccessException {
if (config.getSerializeValueFilter().shouldIgnore(key, value)) {
return;
}
@@ -340,7 +374,7 @@ public class MappingGeneratorImpl implements MappingGenerator {
if (writePrimitives(key, adapted.getClass(), adapted)) {
return;
}
- writeValue(String.class, true, false, false, false, null, key, adapted, null, ignoredProperties);
+ writeValue(String.class, true, false, false, false, null, key, adapted, null, ignoredProperties, null);
return;
} else {
@@ -360,7 +394,7 @@ public class MappingGeneratorImpl implements MappingGenerator {
return;
}
generator.writeStartObject(key);
- doWriteObjectBody(value, ignoredProperties);
+ doWriteObjectBody(value, ignoredProperties, jsonPointer);
generator.writeEnd();
}
}
http://git-wip-us.apache.org/repos/asf/johnzon/blob/0091f201/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/CircularExceptionTest.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/CircularExceptionTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/CircularExceptionTest.java
index 846e469..17fe5f7 100644
--- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/CircularExceptionTest.java
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/CircularExceptionTest.java
@@ -18,6 +18,7 @@
*/
package org.apache.johnzon.mapper;
+import org.junit.Assert;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
@@ -32,4 +33,40 @@ public class CircularExceptionTest {
assertTrue(serialized.contains("\"detailMessage\":\"circular\""));
assertTrue(serialized.contains("\"stackTrace\":[{"));
}
+
+ @Test
+ public void testCyclicPerson() {
+ Person john = new Person("John");
+ Person marry = new Person("Marry");
+
+ john.setMarriedTo(marry);
+ marry.setMarriedTo(john);
+
+ String ser = new MapperBuilder().setAccessModeName("field").build().writeObjectAsString(john);
+ Assert.assertNotNull(ser);
+ assertTrue(ser.contains("\"name\":\"John\""));
+ assertTrue(ser.contains("\"marriedTo\":\"/\""));
+ assertTrue(ser.contains("\"name\":\"Marry\""));
+ }
+
+ public static class Person {
+ private final String name;
+ private Person marriedTo;
+
+ public Person(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Person getMarriedTo() {
+ return marriedTo;
+ }
+
+ public void setMarriedTo(Person marriedTo) {
+ this.marriedTo = marriedTo;
+ }
+ }
}