Skip to content

Commit

Permalink
Fix for owlike#123: Refactored unknown property consumption and switc…
Browse files Browse the repository at this point in the history
…hed to using JsonValueConverter directly
  • Loading branch information
aseovic committed May 21, 2018
1 parent 1617dbf commit 7028dc7
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public Converter<JsonValue> create(Type type, Genson genson) {
});
}

public class JsonValueConverter implements Converter<JsonValue> {
public static class JsonValueConverter implements Converter<JsonValue> {

@Override
public void serialize(JsonValue value, ObjectWriter writer, Context ctx) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public void deserialize(T into, ObjectReader reader, Context ctx) {
reader.skipValue();
}
} else if (unknownPropertyHandler != null) {
unknownPropertyHandler.onUnknownProperty(into, propName, reader, ctx);
unknownPropertyHandler.readUnknownProperty(propName, reader, ctx).accept(into);
} else if (failOnMissingProperty) throw missingPropertyException(propName);
else reader.skipValue();
}
Expand Down Expand Up @@ -157,7 +157,7 @@ protected T _deserWithCtrArgs(ObjectReader reader, Context ctx) {
reader.skipValue();
}
} else if (unknownPropertyHandler != null) {
Consumer<T> callback = unknownPropertyHandler.onUnknownProperty(null, propName, reader, ctx);
Consumer<T> callback = unknownPropertyHandler.readUnknownProperty(propName, reader, ctx);
unknownProperties.add(callback);
} else if (failOnMissingProperty) throw missingPropertyException(propName);
else reader.skipValue();
Expand Down Expand Up @@ -190,9 +190,8 @@ protected T _deserWithCtrArgs(ObjectReader reader, Context ctx) {
property.mutate(bean, newValues[i]);
}
}
if (!unknownProperties.isEmpty()) {
unknownProperties.forEach(callback -> callback.accept(bean));
}
unknownProperties.forEach(callback -> callback.accept(bean));

reader.endObject();
return bean;
}
Expand Down
5 changes: 3 additions & 2 deletions genson/src/main/java/com/owlike/genson/reflect/Evolvable.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.owlike.genson.reflect;

import javax.json.JsonValue;
import java.util.Map;

/**
Expand All @@ -19,12 +20,12 @@ interface Evolvable {
* @param propName property name
* @param propValue property value
*/
void addUnknownProperty(String propName, Object propValue);
void addUnknownProperty(String propName, JsonValue propValue);

/**
* Return a map of unknown properties.
*
* @return a map of unknown properties
*/
Map<String, Object> unknownProperties();
Map<String, JsonValue> unknownProperties();
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.owlike.genson.reflect;

import com.owlike.genson.Context;
import com.owlike.genson.GenericType;
import com.owlike.genson.Converter;
import com.owlike.genson.ext.jsr353.JSR353Bundle;
import com.owlike.genson.stream.ObjectReader;
import com.owlike.genson.stream.ObjectWriter;

import javax.json.JsonValue;

import java.util.Map;
import java.util.function.Consumer;

Expand All @@ -25,41 +27,37 @@
* @author Aleksandar Seovic 2018.05.20
*/
public class EvolvableHandler implements UnknownPropertyHandler {
private static final GenericType<JsonValue> UNKNOWN = new GenericType<JsonValue>() {};
private static final Converter<JsonValue> CONVERTER = new JSR353Bundle.JsonValueConverter();

@Override
public <T> Consumer<T> onUnknownProperty(T target, String propName, ObjectReader reader, Context ctx) {
// TODO: change this to read property as an opaque value, using ObjectReader directly
Object propValue = ctx.genson.deserialize(UNKNOWN, reader, ctx);
public <T> Consumer<T> readUnknownProperty(String propName, ObjectReader reader, Context ctx) {
try {
JsonValue propValue = CONVERTER.deserialize(reader, ctx);

if (target == null) {
// this is a bit ugly...
// the issue is that we may not have a target object while parsing JSON when using creators,
// so we need to store the parsed value somewhere and apply it later
return objTarget -> {
if (objTarget instanceof Evolvable) {
((Evolvable) objTarget).addUnknownProperty(propName, propValue);
}
};
} catch (Exception e) {
throw new RuntimeException(e);
}

if (target instanceof Evolvable) {
((Evolvable) target).addUnknownProperty(propName, propValue);
}
return null;
}

@Override
public <T> void writeUnknownProperties(T source, ObjectWriter writer, Context ctx) {
if (source instanceof Evolvable) {
Map<String, Object> props = ((Evolvable) source).unknownProperties();
if (props != null) {
for (String propName : props.keySet()) {
writer.writeName(propName);
// TODO: change this to write property as an opaque value, using ObjectWriter directly
ctx.genson.serialize(props.get(propName), writer, ctx);
public <T> void writeUnknownProperties(T bean, ObjectWriter writer, Context ctx) {
try {
if (bean instanceof Evolvable) {
Map<String, JsonValue> props = ((Evolvable) bean).unknownProperties();
if (props != null) {
for (String propName : props.keySet()) {
writer.writeName(propName);
CONVERTER.serialize(props.get(propName), writer, ctx);
}
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.owlike.genson.annotation.JsonIgnore;

import javax.json.JsonValue;
import java.util.HashMap;
import java.util.Map;

Expand All @@ -12,18 +13,18 @@
*/
public abstract class EvolvableObject implements Evolvable {
@JsonIgnore
private Map<String, Object> unknownProperties;
private Map<String, JsonValue> unknownProperties;

@Override
public void addUnknownProperty(String propName, Object propValue) {
public void addUnknownProperty(String propName, JsonValue propValue) {
if (unknownProperties == null) {
unknownProperties = new HashMap<>();
}
unknownProperties.put(propName, propValue);
}

@Override
public Map<String, Object> unknownProperties() {
public Map<String, JsonValue> unknownProperties() {
return unknownProperties;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ public interface UnknownPropertyHandler {
* property value somewhere so it can be written later by the
* {@link #writeUnknownProperties} method.
*
* @param target the object we are deserializing JSON into, if known
* @param propName the name of the unknown property
* @param reader the ObjectReader to read property value from
* @param ctx deserialization context
*
* @return the optional Consumer that will be called once the target object is known
* @return the Consumer that will be called with the target bean,
* once the target bean is known
*/
<T> Consumer<T> onUnknownProperty(T target, String propName, ObjectReader reader, Context ctx);
<T> Consumer<T> readUnknownProperty(String propName, ObjectReader reader, Context ctx);

/**
* Write unknown properties encountered during deserialization.
Expand All @@ -45,12 +45,10 @@ public interface UnknownPropertyHandler {
* that want to write unknown properties during serialization. The default
* implementation is a no-op.
*
* @param source the object we are serializing into JSON
* @param bean the object we are serializing into JSON
* @param writer the ObjectReader to read property value from
* @param ctx serialization context
*
* @return a map of unknown properties
*/
default <T> void writeUnknownProperties(T source, ObjectWriter writer, Context ctx) {
default <T> void writeUnknownProperties(T bean, ObjectWriter writer, Context ctx) {
}
}

0 comments on commit 7028dc7

Please sign in to comment.