You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rs...@apache.org on 2017/10/31 21:11:40 UTC
johnzon git commit: JOHNZON-77/JOHNZON-142 implemented
ObjectConverter support for constructors
Repository: johnzon
Updated Branches:
refs/heads/master 08905f99e -> 52f0aab8e
JOHNZON-77/JOHNZON-142 implemented ObjectConverter support for constructors
Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/52f0aab8
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/52f0aab8
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/52f0aab8
Branch: refs/heads/master
Commit: 52f0aab8ed32151b34528e1e48304682a4449f34
Parents: 08905f9
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Tue Oct 31 22:08:53 2017 +0100
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Tue Oct 31 22:09:41 2017 +0100
----------------------------------------------------------------------
.../apache/johnzon/jsonb/JsonbAccessMode.java | 66 +++++++++++++++-----
.../johnzon/mapper/MappingParserImpl.java | 2 +-
.../johnzon/mapper/access/AccessMode.java | 1 +
.../johnzon/mapper/access/BaseAccessMode.java | 10 ++-
.../johnzon/mapper/access/FieldAccessMode.java | 9 +--
.../ObjectConverterWithAnnotationTest.java | 33 ++++++++++
6 files changed, 98 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/johnzon/blob/52f0aab8/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
index 3b020d2..5852177 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JsonbAccessMode.java
@@ -30,6 +30,7 @@ import org.apache.johnzon.jsonb.serializer.JohnzonSerializationContext;
import org.apache.johnzon.jsonb.spi.JohnzonAdapterFactory;
import org.apache.johnzon.mapper.Adapter;
import org.apache.johnzon.mapper.JohnzonAny;
+import org.apache.johnzon.mapper.JohnzonConverter;
import org.apache.johnzon.mapper.ObjectConverter;
import org.apache.johnzon.mapper.TypeAwareAdapter;
import org.apache.johnzon.mapper.access.AccessMode;
@@ -166,11 +167,14 @@ public class JsonbAccessMode implements AccessMode, Closeable {
final String[] params;
final Adapter<?, ?>[] converters;
final Adapter<?, ?>[] itemConverters;
+ final ObjectConverter.Codec<?>[] objectConverters;
if (finalConstructor != null || finalFactory != null) {
types = finalConstructor != null ? finalConstructor.getGenericParameterTypes() : finalFactory.getGenericParameterTypes();
params = new String[types.length];
converters = new Adapter<?, ?>[types.length];
itemConverters = new Adapter<?, ?>[types.length];
+ objectConverters = new ObjectConverter.Codec<?>[types.length];
+
int i = 0;
for (final Parameter parameter : (finalConstructor == null ? finalFactory : finalConstructor).getParameters()) {
final JsonbProperty property = getAnnotation(parameter, JsonbProperty.class);
@@ -179,20 +183,25 @@ public class JsonbAccessMode implements AccessMode, Closeable {
final JsonbTypeAdapter adapter = getAnnotation(parameter, JsonbTypeAdapter.class);
final JsonbDateFormat dateFormat = getAnnotation(parameter, JsonbDateFormat.class);
final JsonbNumberFormat numberFormat = getAnnotation(parameter, JsonbNumberFormat.class);
- if (adapter == null && dateFormat == null && numberFormat == null) {
+ final JohnzonConverter johnzonConverter = getAnnotation(parameter, JohnzonConverter.class);
+ if (adapter == null && dateFormat == null && numberFormat == null && johnzonConverter == null) {
converters[i] = defaultConverters.get(parameter.getType());
itemConverters[i] = null;
} else {
- validateAnnotations(parameter, adapter, dateFormat, numberFormat);
+ validateAnnotations(parameter, adapter, dateFormat, numberFormat, johnzonConverter);
try {
- final Adapter converter = toConverter(parameter.getType(), adapter, dateFormat, numberFormat);
- if (matches(parameter.getParameterizedType(), converter)) {
- converters[i] = converter;
- itemConverters[i] = null;
- } else {
- converters[i] = null;
- itemConverters[i] = converter;
+ if (adapter != null) {
+ final Adapter converter = toConverter(parameter.getType(), adapter, dateFormat, numberFormat);
+ if (matches(parameter.getParameterizedType(), converter)) {
+ converters[i] = converter;
+ itemConverters[i] = null;
+ } else {
+ converters[i] = null;
+ itemConverters[i] = converter;
+ }
+ } else if (johnzonConverter != null) {
+ objectConverters[i] = (ObjectConverter.Codec<?>) johnzonConverter.value().newInstance();
}
} catch (final InstantiationException | IllegalAccessException e) {
throw new IllegalArgumentException(e);
@@ -206,6 +215,7 @@ public class JsonbAccessMode implements AccessMode, Closeable {
params = null;
converters = null;
itemConverters = null;
+ objectConverters = null;
}
return constructor == null && factory == null ? delegate.findFactory(clazz) : (
@@ -241,6 +251,11 @@ public class JsonbAccessMode implements AccessMode, Closeable {
public Adapter<?, ?>[] getParameterItemConverter() {
return itemConverters;
}
+
+ @Override
+ public ObjectConverter.Codec<?>[] getObjectConverter() {
+ return objectConverters;
+ }
} :
new Factory() {
@Override
@@ -277,17 +292,24 @@ public class JsonbAccessMode implements AccessMode, Closeable {
public Adapter<?, ?>[] getParameterItemConverter() {
return itemConverters;
}
+
+ @Override
+ public ObjectConverter.Codec<?>[] getObjectConverter() {
+ return objectConverters;
+ }
});
}
private void validateAnnotations(final Object parameter,
final JsonbTypeAdapter adapter, final JsonbDateFormat dateFormat,
- final JsonbNumberFormat numberFormat) {
+ final JsonbNumberFormat numberFormat,
+ final JohnzonConverter johnzonConverter) {
int notNull = adapter != null ? 1 : 0;
notNull += dateFormat != null ? 1 : 0;
notNull += numberFormat != null ? 1 : 0;
+ notNull += johnzonConverter != null ? 1 : 0;
if (notNull > 1) {
- throw new IllegalArgumentException("Conflicting @JsonbXXX on " + parameter);
+ throw new IllegalArgumentException("Conflicting @JsonbXXX/@JohnzonConverter on " + parameter);
}
}
@@ -685,7 +707,8 @@ public class JsonbAccessMode implements AccessMode, Closeable {
final JsonbTypeAdapter adapter = annotationHolder.getAnnotation(JsonbTypeAdapter.class);
final JsonbDateFormat dateFormat = annotationHolder.getAnnotation(JsonbDateFormat.class);
final JsonbNumberFormat numberFormat = annotationHolder.getAnnotation(JsonbNumberFormat.class);
- validateAnnotations(annotationHolder, adapter, dateFormat, numberFormat);
+ final JohnzonConverter johnzonConverter = annotationHolder.getAnnotation(JohnzonConverter.class);
+ validateAnnotations(annotationHolder, adapter, dateFormat, numberFormat, johnzonConverter);
try {
converter = adapter == null && dateFormat == null && numberFormat == null ?
@@ -705,8 +728,12 @@ public class JsonbAccessMode implements AccessMode, Closeable {
toRelease.add(instance);
reader = (jsonObject, targetType, parser) ->
instance.getValue().deserialize(parserFactory.get().createParser(jsonObject), new JohnzonDeserializationContext(parser), targetType);
- } else {
- reader = null;
+ } else if (johnzonConverter != null) {
+ try {
+ reader = (ObjectConverter.Reader) johnzonConverter.value().newInstance();
+ } catch (final InstantiationException | IllegalAccessException e) {
+ throw new IllegalArgumentException(e);
+ }
}
}
}
@@ -720,7 +747,8 @@ public class JsonbAccessMode implements AccessMode, Closeable {
final JsonbTypeAdapter adapter = initialReader.getAnnotation(JsonbTypeAdapter.class);
final JsonbDateFormat dateFormat = initialReader.getAnnotation(JsonbDateFormat.class);
final JsonbNumberFormat numberFormat = initialReader.getAnnotation(JsonbNumberFormat.class);
- validateAnnotations(initialReader, adapter, dateFormat, numberFormat);
+ final JohnzonConverter johnzonConverter = initialReader.getAnnotation(JohnzonConverter.class);
+ validateAnnotations(initialReader, adapter, dateFormat, numberFormat, johnzonConverter);
try {
converter = adapter == null && dateFormat == null && numberFormat == null ?
@@ -740,8 +768,12 @@ public class JsonbAccessMode implements AccessMode, Closeable {
toRelease.add(instance);
writer = (instance1, jsonbGenerator) ->
instance.getValue().serialize(instance1, jsonbGenerator.getJsonGenerator(), new JohnzonSerializationContext(jsonbGenerator));
- } else {
- writer = null;
+ } else if (johnzonConverter != null) {
+ try {
+ writer = (ObjectConverter.Writer) johnzonConverter.value().newInstance();
+ } catch (final InstantiationException | IllegalAccessException e) {
+ throw new IllegalArgumentException(e);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/johnzon/blob/52f0aab8/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
index 383b10c..41731d4 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MappingParserImpl.java
@@ -666,7 +666,7 @@ public class MappingParserImpl implements MappingParser {
mapping.factory.getParameterConverter()[i],
mapping.factory.getParameterItemConverter()[i],
mapping.factory.getParameterTypes()[i],
- null,
+ mapping.factory.getObjectConverter()[i],
config.isDeduplicateObjects() ? new JsonPointerTracker(jsonPointer, paramName) : null); //X TODO ObjectConverter in @JOhnzonConverter with Constructors!
}
http://git-wip-us.apache.org/repos/asf/johnzon/blob/52f0aab8/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/AccessMode.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/AccessMode.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/AccessMode.java
index 8575aa3..4d590bf 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/AccessMode.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/AccessMode.java
@@ -52,6 +52,7 @@ public interface AccessMode {
String[] getParameterNames();
Adapter<?, ?>[] getParameterConverter();
Adapter<?, ?>[] getParameterItemConverter();
+ ObjectConverter.Codec<?>[] getObjectConverter();
}
Factory findFactory(Class<?> clazz);
http://git-wip-us.apache.org/repos/asf/johnzon/blob/52f0aab8/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
index e1bba2e..36200ad 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/BaseAccessMode.java
@@ -134,6 +134,7 @@ public abstract class BaseAccessMode implements AccessMode {
final String[] constructorParameters;
final Adapter<?, ?>[] constructorParameterConverters;
final Adapter<?, ?>[] constructorItemParameterConverters;
+ final ObjectConverter.Codec<?>[] objectConverters;
if (constructorHasArguments) {
factoryParameterTypes = constructor.getGenericParameterTypes();
@@ -143,6 +144,7 @@ public abstract class BaseAccessMode implements AccessMode {
constructorParameterConverters = new Adapter<?, ?>[constructor.getGenericParameterTypes().length];
constructorItemParameterConverters = new Adapter<?, ?>[constructorParameterConverters.length];
+ objectConverters = new ObjectConverter.Codec[constructorParameterConverters.length];
for (int i = 0; i < constructorParameters.length; i++) {
for (final Annotation a : constructor.getParameterAnnotations()[i]) {
if (a.annotationType() == JohnzonConverter.class) {
@@ -158,7 +160,7 @@ public abstract class BaseAccessMode implements AccessMode {
constructorItemParameterConverters[i] = converter;
}
} else {
- throw new UnsupportedOperationException("TODO implement");
+ objectConverters[i] = (ObjectConverter.Codec<?>) mapperConverter;
}
} catch (final Exception e) {
throw new IllegalArgumentException(e);
@@ -171,6 +173,7 @@ public abstract class BaseAccessMode implements AccessMode {
constructorParameters = null;
constructorParameterConverters = null;
constructorItemParameterConverters = null;
+ objectConverters = null;
}
final Constructor<?> cons = constructor;
@@ -213,6 +216,11 @@ public abstract class BaseAccessMode implements AccessMode {
public Adapter<?, ?>[] getParameterItemConverter() {
return constructorItemParameterConverters;
}
+
+ @Override
+ public ObjectConverter.Codec<?>[] getObjectConverter() {
+ return objectConverters;
+ }
};
}
http://git-wip-us.apache.org/repos/asf/johnzon/blob/52f0aab8/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAccessMode.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAccessMode.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAccessMode.java
index cff4358..f2cec48 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAccessMode.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/access/FieldAccessMode.java
@@ -39,7 +39,7 @@ public class FieldAccessMode extends BaseAccessMode {
@Override
public Map<String, Reader> doFindReaders(final Class<?> clazz) {
final Map<String, Reader> readers = new HashMap<String, Reader>();
- for (final Map.Entry<String, Field> f : fields(clazz).entrySet()) {
+ for (final Map.Entry<String, Field> f : fields(clazz, true).entrySet()) {
final String key = f.getKey();
if (isIgnored(key) || Meta.getAnnotation(f.getValue(), JohnzonAny.class) != null) {
continue;
@@ -54,7 +54,7 @@ public class FieldAccessMode extends BaseAccessMode {
@Override
public Map<String, Writer> doFindWriters(final Class<?> clazz) {
final Map<String, Writer> writers = new HashMap<String, Writer>();
- for (final Map.Entry<String, Field> f : fields(clazz).entrySet()) {
+ for (final Map.Entry<String, Field> f : fields(clazz, false).entrySet()) {
final String key = f.getKey();
if (isIgnored(key)) {
continue;
@@ -75,7 +75,7 @@ public class FieldAccessMode extends BaseAccessMode {
return key.contains("$");
}
- protected Map<String, Field> fields(final Class<?> clazz) {
+ protected Map<String, Field> fields(final Class<?> clazz, boolean includeFinalFields) {
final Map<String, Field> fields = new HashMap<String, Field>();
Class<?> current = clazz;
while (current != null && current != Object.class) {
@@ -84,7 +84,8 @@ public class FieldAccessMode extends BaseAccessMode {
final int modifiers = f.getModifiers();
if (fields.containsKey(name)
|| Modifier.isStatic(modifiers)
- || Modifier.isTransient(modifiers)) {
+ || Modifier.isTransient(modifiers)
+ || (!includeFinalFields && Modifier.isFinal(modifiers))) {
continue;
}
fields.put(name, f);
http://git-wip-us.apache.org/repos/asf/johnzon/blob/52f0aab8/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectConverterWithAnnotationTest.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectConverterWithAnnotationTest.java b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectConverterWithAnnotationTest.java
index 510672d..c465f8b 100644
--- a/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectConverterWithAnnotationTest.java
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectConverterWithAnnotationTest.java
@@ -24,6 +24,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import javax.json.JsonObject;
+import java.beans.ConstructorProperties;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;
@@ -159,6 +160,38 @@ public class ObjectConverterWithAnnotationTest {
Assert.assertEquals(expected, tourDeFlanderen);
}
+ @Test
+ public void testDeserializeObjectWithAnnotatedConsturctorParameter() {
+
+ String json = "{" +
+ "\"bike\": {" +
+ "\"" + MANUFACTURER_ID + "\":1," +
+ "\"" + TYPE_INDEX + "\":0" +
+ "}" +
+ "}";
+
+ Mapper mapper = new MapperBuilder().setAccessModeName(accessMode)
+ .setReadAttributeBeforeWrite(true)
+ .build();
+
+ BikeWrapper bikeWrapper = mapper.readObject(json, BikeWrapper.class);
+ Assert.assertNotNull(bikeWrapper);
+ Assert.assertEquals(bikeWrapper.getBike(), new Bike("Canyon", BikeType.ROAD));
+ }
+
+ public static class BikeWrapper {
+ private final Bike bike;
+
+ @ConstructorProperties(value = "bike")
+ BikeWrapper(@JohnzonConverter(value = BikeConverter.class) Bike bike) {
+ this.bike = bike;
+ }
+
+ Bike getBike() {
+ return bike;
+ }
+ }
+
public static class CycleRace {
private boolean monument;