You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rm...@apache.org on 2016/03/23 14:18:57 UTC
incubator-johnzon git commit: JOHNZON-70 ReadAttributeBeforeWrite
option for mapper
Repository: incubator-johnzon
Updated Branches:
refs/heads/master 01bae73bf -> c4c6f2900
JOHNZON-70 ReadAttributeBeforeWrite option for mapper
Project: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/commit/c4c6f290
Tree: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/tree/c4c6f290
Diff: http://git-wip-us.apache.org/repos/asf/incubator-johnzon/diff/c4c6f290
Branch: refs/heads/master
Commit: c4c6f2900bc6b2a9a4c4f5e2e796108509f03cd4
Parents: 01bae73
Author: Romain manni-Bucau <rm...@gmail.com>
Authored: Wed Mar 23 14:18:16 2016 +0100
Committer: Romain manni-Bucau <rm...@gmail.com>
Committed: Wed Mar 23 14:18:44 2016 +0100
----------------------------------------------------------------------
.../jaxrs/ConfigurableJohnzonProvider.java | 4 +++
.../WildcardConfigurableJohnzonProvider.java | 4 +++
.../apache/johnzon/jsonb/JohnzonBuilder.java | 5 ++-
.../org/apache/johnzon/jsonb/AdapterTest.java | 22 +++++++++---
.../java/org/apache/johnzon/mapper/Mapper.java | 37 ++++++++++++++------
.../apache/johnzon/mapper/MapperBuilder.java | 9 ++++-
6 files changed, 65 insertions(+), 16 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c4c6f290/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
----------------------------------------------------------------------
diff --git a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
index e942385..ce783ab 100644
--- a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
+++ b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/ConfigurableJohnzonProvider.java
@@ -195,4 +195,8 @@ public class ConfigurableJohnzonProvider<T> implements MessageBodyWriter<T>, Mes
public void setEncoding(final String encoding) {
builder.setEncoding(encoding);
}
+
+ public void setReadAttributeBeforeWrite(final boolean rabw) {
+ builder.setReadAttributeBeforeWrite(rabw);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c4c6f290/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java
----------------------------------------------------------------------
diff --git a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java
index 23f51e0..f404167 100644
--- a/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java
+++ b/johnzon-jaxrs/src/main/java/org/apache/johnzon/jaxrs/WildcardConfigurableJohnzonProvider.java
@@ -200,6 +200,10 @@ public class WildcardConfigurableJohnzonProvider<T> implements MessageBodyWriter
builder.setTreatByteArrayAsBase64(treatByteArrayAsBase64);
}
+ public void setReadAttributeBeforeWrite(final boolean rabw) {
+ builder.setReadAttributeBeforeWrite(rabw);
+ }
+
public void setEncoding(final String encoding) {
builder.setEncoding(encoding);
}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c4c6f290/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
index b66d90e..d987230 100644
--- a/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
+++ b/johnzon-jsonb/src/main/java/org/apache/johnzon/jsonb/JohnzonBuilder.java
@@ -202,7 +202,7 @@ public class JohnzonBuilder implements JsonbBuilder {
}));
config.getProperty(JsonbConfig.STRICT_IJSON).map(Boolean.class::cast).ifPresent(ijson -> {
- // no-op: https://tools.ietf.org/html/rfc7493 the only MUST of the spec sould be fine by default
+ // no-op: https://tools.ietf.org/html/rfc7493 the only MUST of the spec should be fine by default
});
config.getProperty(JsonbConfig.BINARY_DATA_STRATEGY).map(String.class::cast).ifPresent(bin -> {
@@ -233,6 +233,9 @@ public class JohnzonBuilder implements JsonbBuilder {
getBeanManager(); // force detection
+ builder.setReadAttributeBeforeWrite(
+ config.getProperty("johnzon.readAttributeBeforeWrite").map(Boolean.class::cast).orElse(false));
+
final boolean useCdi = cdiIntegration != null && cdiIntegration.isCanWrite();
final Mapper mapper = builder.addCloseable(accessMode).build();
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c4c6f290/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/AdapterTest.java
----------------------------------------------------------------------
diff --git a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/AdapterTest.java b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/AdapterTest.java
index 538399c..05b80da 100644
--- a/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/AdapterTest.java
+++ b/johnzon-jsonb/src/test/java/org/apache/johnzon/jsonb/AdapterTest.java
@@ -63,7 +63,10 @@ public class AdapterTest {
final Polymorphism foo = new Polymorphism();
foo.bars = new ArrayList<>(asList(bar, bar2));
- final Jsonb jsonb = JsonbBuilder.create(new JsonbConfig().withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL));
+ final Jsonb jsonb = JsonbBuilder.create(
+ new JsonbConfig()
+ .setProperty("johnzon.readAttributeBeforeWrite", true)
+ .withPropertyOrderStrategy(PropertyOrderStrategy.LEXICOGRAPHICAL) /* assertEquals() order */);
final String toString = jsonb.toJson(foo);
assertEquals("{\"bars\":[" +
@@ -75,10 +78,8 @@ public class AdapterTest {
assertEquals(11, read.bars.get(0).value);
assertTrue(Bar.class == read.bars.get(0).getClass());
assertEquals(21, read.bars.get(1).value);
- /* not yet working since model is statically typed
assertTrue(Bar2.class == read.bars.get(1).getClass());
assertEquals(22, Bar2.class.cast(read.bars.get(1)).value2);
- */
}
public static class Polymorphism {
@@ -88,9 +89,22 @@ public class AdapterTest {
public static class TypeInstance {
- public String type;
+ private String type;
private Bar value;
+ public String getType() {
+ return type;
+ }
+
+ public void setType(final String type) {
+ this.type = type;
+ try {
+ this.value = Bar.class.cast(Thread.currentThread().getContextClassLoader().loadClass(type).newInstance());
+ } catch (final InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
public Bar getValue() {
return value;
}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c4c6f290/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
index d24e44c..f3bbcd9 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/Mapper.java
@@ -99,6 +99,7 @@ public class Mapper implements Closeable {
protected final boolean skipEmptyArray;
protected final boolean treatByteArrayAsBase64;
protected final boolean treatByteArrayAsBase64URL;
+ protected final boolean readAttributeBeforeWrite;
protected final Charset encoding;
protected final ReaderHandler readerHandler;
protected final Collection<Closeable> closeables;
@@ -108,7 +109,7 @@ public class Mapper implements Closeable {
final boolean doClose, final Map<AdapterKey, Adapter<?, ?>> adapters,
final int version, final Comparator<String> attributeOrder, final boolean skipNull, final boolean skipEmptyArray,
final AccessMode accessMode, final boolean treatByteArrayAsBase64, final boolean treatByteArrayAsBase64URL, final Charset encoding,
- final Collection<Closeable> closeables) {
+ final Collection<Closeable> closeables, final boolean readAttributeBeforeWrite) {
// CHECKSTYLE:ON
this.readerFactory = readerFactory;
this.generatorFactory = generatorFactory;
@@ -123,6 +124,7 @@ public class Mapper implements Closeable {
this.encoding = encoding;
this.readerHandler = ReaderHandler.create(readerFactory);
this.closeables = closeables;
+ this.readAttributeBeforeWrite = readAttributeBeforeWrite;
}
private static JsonGenerator writePrimitives(final JsonGenerator generator, final Object value) {
@@ -749,7 +751,7 @@ public class Mapper implements Closeable {
} else if (JsonString.class.isInstance(jsonValue) && any) {
map.put(value.getKey(), JsonString.class.cast(jsonValue).getString());
} else {
- map.put(convertTo(keyType, value.getKey()), toObject(jsonValue, fieldArgTypes[1], null));
+ map.put(convertTo(keyType, value.getKey()), toObject(null, jsonValue, fieldArgTypes[1], null));
}
}
return map;
@@ -758,7 +760,7 @@ public class Mapper implements Closeable {
} else if (Map.class == type || HashMap.class == type || LinkedHashMap.class == type) {
final LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
for (final Map.Entry<String, JsonValue> value : object.entrySet()) {
- map.put(value.getKey(), toObject(value.getValue(), Object.class, null));
+ map.put(value.getKey(), toObject(null, value.getValue(), Object.class, null));
}
return map;
}
@@ -788,7 +790,18 @@ public class Mapper implements Closeable {
if (jsonValue == JsonValue.NULL) { // forced
setterMethod.write(t, null);
} else {
- final Object convertedValue = toValue(jsonValue, value.converter, value.itemConverter, value.paramType);
+ Object existingInstance = null;
+ if (readAttributeBeforeWrite) {
+ final Mappings.Getter getter = classMapping.getters.get(setter.getKey());
+ if (getter != null) {
+ try {
+ existingInstance = getter.reader.read(t);
+ } catch (final RuntimeException re) {
+ // backward compatibility
+ }
+ }
+ }
+ final Object convertedValue = toValue(existingInstance, jsonValue, value.converter, value.itemConverter, value.paramType);
if (convertedValue != null) {
setterMethod.write(t, convertedValue);
}
@@ -798,9 +811,10 @@ public class Mapper implements Closeable {
return t;
}
- private Object toValue(final JsonValue jsonValue, final Adapter converter, final Adapter itemConverter, final Type type) throws Exception {
+ private Object toValue(final Object baseInstance, final JsonValue jsonValue, final Adapter converter,
+ final Adapter itemConverter, final Type type) throws Exception {
return converter == null ?
- toObject(jsonValue, type, itemConverter) : jsonValue.getValueType() == ValueType.STRING ?
+ toObject(baseInstance, jsonValue, type, itemConverter) : jsonValue.getValueType() == ValueType.STRING ?
converter.to(JsonString.class.cast(jsonValue).getString()) :
convertTo(converter, jsonValue);
}
@@ -833,13 +847,15 @@ public class Mapper implements Closeable {
final Object[] objects = new Object[length];
for (int i = 0; i < length; i++) {
objects[i] = toValue(
+ null,
object.get(mapping.factory.getParameterNames()[i]), mapping.factory.getParameterConverter()[i],
mapping.factory.getParameterItemConverter()[i], mapping.factory.getParameterTypes()[i]);
}
return objects;
}
- private Object toObject(final JsonValue jsonValue, final Type type, final Adapter itemConverter) throws Exception {
+ private Object toObject(final Object baseInstance, final JsonValue jsonValue,
+ final Type type, final Adapter itemConverter) throws Exception {
if (jsonValue == null || JsonValue.NULL == jsonValue) {
return null;
}
@@ -884,7 +900,8 @@ public class Mapper implements Closeable {
}
final boolean typedAdapter = TypeAwareAdapter.class.isInstance(itemConverter);
final Object object = buildObject(
- typedAdapter ? TypeAwareAdapter.class.cast(itemConverter).getTo() : type,
+ baseInstance != null ? baseInstance.getClass() : (
+ typedAdapter ? TypeAwareAdapter.class.cast(itemConverter).getTo() : type),
JsonObject.class.cast(jsonValue));
return typedAdapter ? itemConverter.to(object) : object;
} else if (JsonArray.class.isInstance(jsonValue)) {
@@ -992,7 +1009,7 @@ public class Mapper implements Closeable {
}
for (final JsonValue value : jsonArray) {
- collection.add(value == JsonValue.NULL ? null : toObject(value, mapping.arg, itemConverter));
+ collection.add(value == JsonValue.NULL ? null : toObject(null, value, mapping.arg, itemConverter));
}
if (EnumSet.class == mapping.raw) {
@@ -1013,7 +1030,7 @@ public class Mapper implements Closeable {
final Object array = Array.newInstance(componentType, jsonArray.size());
int i = 0;
for (final JsonValue value : jsonArray) {
- Array.set(array, i++, toObject(value, componentType, itemConverter));
+ Array.set(array, i++, toObject(null, value, componentType, itemConverter));
}
return array;
}
http://git-wip-us.apache.org/repos/asf/incubator-johnzon/blob/c4c6f290/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
----------------------------------------------------------------------
diff --git a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
index 443903b..e78f2f2 100644
--- a/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
+++ b/johnzon-mapper/src/main/java/org/apache/johnzon/mapper/MapperBuilder.java
@@ -114,6 +114,7 @@ public class MapperBuilder {
private boolean supportConstructors;
private Charset encoding = Charset.forName(System.getProperty("johnzon.mapper.encoding", "UTF-8"));
private boolean useGetterForCollections;
+ private boolean readAttributeBeforeWrite;
private String accessModeName;
private final Collection<Closeable> closeables = new ArrayList<Closeable>();
@@ -171,7 +172,8 @@ public class MapperBuilder {
accessMode,
treatByteArrayAsBase64, treatByteArrayAsBase64URL,
encoding,
- closeables);
+ closeables,
+ readAttributeBeforeWrite);
}
public MapperBuilder addCloseable(final Closeable closeable) {
@@ -323,4 +325,9 @@ public class MapperBuilder {
this.encoding = Charset.forName(encoding);
return this;
}
+
+ public MapperBuilder setReadAttributeBeforeWrite(final boolean readAttributeBeforeWrite) {
+ this.readAttributeBeforeWrite = readAttributeBeforeWrite;
+ return this;
+ }
}