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 2016/05/10 16:46:10 UTC
[2/4] incubator-johnzon git commit: JOHNZON-77 implemented
ObjectConverter support for @JohnzonConverter
JOHNZON-77 implemented ObjectConverter support for @JohnzonConverter
Project: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/commit/c369178b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/tree/c369178b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/diff/c369178b
Branch: refs/heads/master
Commit: c369178b404e668da69589e5acd27b25ea3d2ec5
Parents: ef9e19e
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Tue May 10 12:20:34 2016 +0200
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Tue May 10 12:20:34 2016 +0200
----------------------------------------------------------------------
.../johnzon/mapper/MappingGeneratorImpl.java | 19 +-
.../johnzon/mapper/MappingParserImpl.java | 17 +-
.../org/apache/johnzon/mapper/Mappings.java | 99 +++++---
.../ObjectConverterWithAnnotationTest.java | 229 +++++++++++++++++++
4 files changed, 322 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c369178b/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 bc0f531..48c999d 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
@@ -133,7 +133,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);
+ key == null ? "null" : key.toString(), value, null);
}
return generator;
}
@@ -260,7 +260,7 @@ public class MappingGeneratorImpl implements MappingGenerator {
getter.collection, getter.map,
getter.itemConverter,
getterEntry.getKey(),
- val);
+ val, getter.objectConverter);
}
return generator;
}
@@ -269,7 +269,7 @@ public class MappingGeneratorImpl implements MappingGenerator {
final boolean primitive, final boolean array,
final boolean collection, final boolean map,
final Adapter itemConverter,
- final String key, final Object value) throws InvocationTargetException, IllegalAccessException {
+ final String key, final Object value, final ObjectConverter objectConverter) throws InvocationTargetException, IllegalAccessException {
if (array) {
final int length = Array.getLength(value);
if (length == 0 && config.isSkipEmptyArray()) {
@@ -315,13 +315,18 @@ public class MappingGeneratorImpl implements MappingGenerator {
if (writePrimitives(key, adapted.getClass(), adapted)) {
return;
}
- writeValue(String.class, true, false, false, false, null, key, adapted);
+ writeValue(String.class, true, false, false, false, null, key, adapted, null);
return;
} else {
- ObjectConverter objectConverter = config.findObjectConverter(type);
- if (objectConverter != null) {
+
+ ObjectConverter objectConverterToUse = objectConverter;
+ if (objectConverterToUse == null) {
+ objectConverterToUse = config.findObjectConverter(type);
+ }
+
+ if (objectConverterToUse != null) {
generator.writeStartObject(key);
- objectConverter.writeJson(value, this);
+ objectConverterToUse.writeJson(value, this);
generator.writeEnd();
return;
}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c369178b/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 ad6feeb..87ceb49 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
@@ -294,7 +294,7 @@ public class MappingParserImpl implements MappingParser {
}
}
}
- final Object convertedValue = toValue(existingInstance, jsonValue, value.converter, value.itemConverter, value.paramType);
+ final Object convertedValue = toValue(existingInstance, jsonValue, value.converter, value.itemConverter, value.paramType, value.objectConverter);
if (convertedValue != null) {
setterMethod.write(t, convertedValue);
}
@@ -527,14 +527,25 @@ public class MappingParserImpl implements MappingParser {
object.get(mapping.factory.getParameterNames()[i]),
mapping.factory.getParameterConverter()[i],
mapping.factory.getParameterItemConverter()[i],
- mapping.factory.getParameterTypes()[i]);
+ mapping.factory.getParameterTypes()[i],
+ null); //X TODO ObjectConverter in @JOhnzonConverter with Constructors!
}
return objects;
}
private Object toValue(final Object baseInstance, final JsonValue jsonValue, final Adapter converter,
- final Adapter itemConverter, final Type type) {
+ final Adapter itemConverter, final Type type, final ObjectConverter objectConverter) {
+
+ if (objectConverter != null) {
+
+ if (jsonValue instanceof JsonObject) {
+ return objectConverter.fromJson((JsonObject) jsonValue, type, this);
+ } else {
+ throw new UnsupportedOperationException("Array handling with ObjectConverter currently not implemented");
+ }
+ }
+
return converter == null ? toObject(baseInstance, jsonValue, type, itemConverter)
: jsonValue.getValueType() == JsonValue.ValueType.STRING ? converter.to(JsonString.class.cast(jsonValue).getString())
: convertTo(converter, jsonValue);
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c369178b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
index 52a6eca..8c1154b 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mappings.java
@@ -85,6 +85,7 @@ public class Mappings {
final int version;
final Adapter converter;
final Adapter itemConverter;
+ final ObjectConverter objectConverter;
final boolean primitive;
final boolean array;
final boolean map;
@@ -93,23 +94,43 @@ public class Mappings {
public Getter(final AccessMode.Reader reader,
final boolean primitive, final boolean array,
final boolean collection, final boolean map,
- final Adapter<?, ?> converter,
+ final MapperConverter converter,
final int version) {
this.reader = reader;
this.version = version;
this.array = array;
this.collection = collection;
this.primitive = primitive;
- if (converter != null && matches(reader.getType(), converter)) {
- this.converter = converter;
- this.itemConverter = null;
- } else if (converter != null) {
- this.converter = null;
- this.itemConverter = converter;
- } else {
- this.converter = null;
- this.itemConverter = null;
+
+ Adapter theConverter = null;
+ Adapter theItemConverter = null;
+ ObjectConverter theObjectConverter = null;
+
+ if (converter != null) {
+
+ if (converter instanceof ObjectConverter) {
+ theObjectConverter = (ObjectConverter) converter;
+ } else {
+
+ Adapter adapter;
+ if (converter instanceof Converter) {
+ adapter = new ConverterAdapter((Converter) converter);
+ } else {
+ adapter = (Adapter) converter;
+ }
+
+ if (matches(reader.getType(), adapter)) {
+ theConverter = adapter;
+ } else {
+ theItemConverter = adapter;
+ }
+ }
}
+
+ this.converter = theConverter;
+ this.itemConverter = theItemConverter;
+ this.objectConverter = theObjectConverter;
+
this.map = map && this.converter == null;
}
@@ -132,29 +153,49 @@ public class Mappings {
public final AccessMode.Writer writer;
public final int version;
public final Type paramType;
- public final Adapter<?, ?> converter;
- public final Adapter<?, ?> itemConverter;
+ public final Adapter converter;
+ public final Adapter itemConverter;
+ public final ObjectConverter objectConverter;
public final boolean primitive;
public final boolean array;
public Setter(final AccessMode.Writer writer, final boolean primitive, final boolean array,
- final Type paramType, final Adapter<?, ?> converter,
+ final Type paramType, final MapperConverter converter,
final int version) {
this.writer = writer;
this.paramType = paramType;
this.version = version;
this.primitive = primitive;
this.array = array;
- if (converter != null && matches(writer.getType(), converter)) {
- this.converter = converter;
- this.itemConverter = null;
- } else if (converter != null) {
- this.converter = null;
- this.itemConverter = converter;
- } else {
- this.converter = null;
- this.itemConverter = null;
+
+ Adapter theConverter = null;
+ Adapter theItemConverter = null;
+ ObjectConverter theObjectConverter = null;
+
+ if (converter != null) {
+
+ if (converter instanceof ObjectConverter) {
+ theObjectConverter = (ObjectConverter) converter;
+ } else {
+
+ Adapter adapter;
+ if (converter instanceof Converter) {
+ adapter = new ConverterAdapter((Converter) converter);
+ } else {
+ adapter = (Adapter) converter;
+ }
+
+ if (matches(writer.getType(), adapter)) {
+ theConverter = adapter;
+ } else {
+ theItemConverter = adapter;
+ }
+ }
}
+
+ this.converter = theConverter;
+ this.itemConverter = theItemConverter;
+ this.objectConverter = theObjectConverter;
}
@Override
@@ -431,8 +472,8 @@ public class Mappings {
setters.put(key, new Setter(newSetter == null ? newWriter : new CompositeWriter(newSetter.writer, newWriter), false, false, VIRTUAL_TYPE, null, -1));
}
- private Adapter findConverter(final boolean copyDate, final AccessMode.DecoratedType decoratedType) {
- Adapter converter = decoratedType.findConverter();
+ private MapperConverter findConverter(final boolean copyDate, final AccessMode.DecoratedType decoratedType) {
+ MapperConverter converter = decoratedType.findConverter();
if (converter != null) {
return converter;
}
@@ -442,13 +483,7 @@ public class Mappings {
Type typeToTest = decoratedType.getType();
if (annotation != null) {
try {
- MapperConverter mapperConverter = annotation.value().newInstance();
- if (mapperConverter instanceof Converter) {
- converter = new ConverterAdapter((Converter) mapperConverter);
- } else {
- throw new UnsupportedOperationException("TODO implement");
- }
-
+ converter = annotation.value().newInstance();
} catch (final Exception e) {
throw new IllegalArgumentException(e);
}
@@ -472,7 +507,7 @@ public class Mappings {
converter = adapters.get(key); // first ensure user didnt override it
if (converter == null) {
converter = new ConverterAdapter(new EnumConverter(type));
- adapters.put(key, converter);
+ adapters.put(key, (Adapter<?, ?>) converter);
}
} else {
for (final Map.Entry<AdapterKey, Adapter<?, ?>> adapterEntry : adapters.entrySet()) {
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c369178b/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
new file mode 100644
index 0000000..343a5a8
--- /dev/null
+++ b/johnzon-mapper/src/test/java/org/apache/johnzon/mapper/ObjectConverterWithAnnotationTest.java
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.johnzon.mapper;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import javax.json.JsonObject;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(value = Parameterized.class)
+public class ObjectConverterWithAnnotationTest {
+
+ private static final String MANUFACTURER_ID = "manufacturerId";
+ private static final String TYPE_INDEX = "typeIndex";
+
+
+ @Parameterized.Parameter
+ public String accessMode;
+
+
+ @Parameterized.Parameters()
+ public static Iterable<String> accessModes() {
+ return Arrays.asList("field", "method", "both", "strict-method");
+ }
+
+
+ @Test
+ public void testSerializeWithObjectConverter() {
+
+ Mapper mapper = new MapperBuilder().setAccessModeName(accessMode)
+ .build();
+
+ Cyclist cyclist = new Cyclist("Peter Sagan", new Bike("Specialized / S-Works", BikeType.ROAD));
+
+ String json = mapper.writeObjectAsString(cyclist);
+ Assert.assertNotNull(json);
+ Assert.assertEquals("{" +
+ "\"name\":\"Peter Sagan\"," +
+ "\"bike\":{" +
+ "\"" + MANUFACTURER_ID + "\":0," +
+ "\"" + TYPE_INDEX + "\":0" +
+ "}" +
+ "}", json);
+
+ }
+
+ @Test
+ public void testDeserializeWithObjectConverter() {
+
+ Mapper mapper = new MapperBuilder().setAccessModeName(accessMode)
+ .build();
+
+ String json = "{" +
+ "\"name\":\"Jan Frodeno\"," +
+ "\"bike\":{" +
+ "\"" + MANUFACTURER_ID + "\":1," +
+ "\"" + TYPE_INDEX + "\":2" +
+ "}" +
+ "}";
+
+ Cyclist expected = new Cyclist("Jan Frodeno", new Bike("Canyon", BikeType.TRIATHLON));
+
+ Object cyclist = mapper.readObject(json, Cyclist.class);
+ Assert.assertNotNull(cyclist);
+ Assert.assertEquals(expected, cyclist);
+ }
+
+
+
+ public static class Cyclist {
+
+ private String name;
+
+ @JohnzonConverter(value = BikeConverter.class)
+ private Bike bike;
+
+ public Cyclist() {
+ }
+
+ public Cyclist(String name, Bike bike) {
+ this.name = name;
+ this.bike = bike;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ @JohnzonConverter(value = BikeConverter.class)
+ public Bike getBike() {
+ return bike;
+ }
+
+ @JohnzonConverter(value = BikeConverter.class)
+ public void setBike(Bike bike) {
+ this.bike = bike;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Cyclist cyclist = (Cyclist) o;
+
+ if (name != null ? !name.equals(cyclist.name) : cyclist.name != null) {
+ return false;
+ }
+ return bike != null ? bike.equals(cyclist.bike) : cyclist.bike == null;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name != null ? name.hashCode() : 0;
+ result = 31 * result + (bike != null ? bike.hashCode() : 0);
+ return result;
+ }
+ }
+
+ public static class Bike {
+ private String manufacturer;
+ private BikeType type;
+
+ public Bike() {
+ }
+
+ public Bike(String manufacturer, BikeType type) {
+ this.manufacturer = manufacturer;
+ this.type = type;
+ }
+
+ public String getManufacturer() {
+ return manufacturer;
+ }
+
+ public void setManufacturer(String manufacturer) {
+ this.manufacturer = manufacturer;
+ }
+
+ public BikeType getType() {
+ return type;
+ }
+
+ public void setType(BikeType type) {
+ this.type = type;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ Bike bike = (Bike) o;
+
+ if (manufacturer != null ? !manufacturer.equals(bike.manufacturer) : bike.manufacturer != null) {
+ return false;
+ }
+ return type == bike.type;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = manufacturer != null ? manufacturer.hashCode() : 0;
+ result = 31 * result + (type != null ? type.hashCode() : 0);
+ return result;
+ }
+ }
+
+ public enum BikeType {
+ ROAD,
+ TIME_TRIAL,
+ TRIATHLON
+ }
+
+ public static class BikeConverter implements ObjectConverter<Bike> {
+
+ public static final List<String> MANUFACTURERS = Arrays.asList("Specialized / S-Works", "Canyon", "Trek", "Scott");
+
+
+ @Override
+ public void writeJson(Bike instance, MappingGenerator jsonbGenerator) {
+ jsonbGenerator.getJsonGenerator().write(MANUFACTURER_ID, MANUFACTURERS.indexOf(instance.getManufacturer()));
+
+ // i know you should never use this in production but its good for our sample ;)
+ jsonbGenerator.getJsonGenerator().write(TYPE_INDEX, instance.getType().ordinal());
+ }
+
+ @Override
+ public Bike fromJson(JsonObject jsonObject, Type targetType, MappingParser parser) {
+ return new Bike(MANUFACTURERS.get(jsonObject.getInt(MANUFACTURER_ID)),
+ BikeType.values()[jsonObject.getInt(TYPE_INDEX)]);
+ }
+ }
+}