Skip to content

Commit

Permalink
Polished PR #4 and documentation.
Browse files Browse the repository at this point in the history
Reverted ea29311 for now.
  • Loading branch information
jonpeterson committed Sep 19, 2016
1 parent b0558d6 commit 9b45ada
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,17 @@
String currentVersion();

/**
* @return the version to convert the model to during serialization; this can be overridden by using
* {@link JsonSerializeToVersion}
* @return the default version to convert the model to during serialization when no field or getter method is
* annotated with {@link JsonSerializeToVersion}; if not set, the current version is used
*/
String defaultSerializeToVersion() default "";

/**
* @return the default version to convert the model to during deserialization when no model version property is
* present; if not set, an exception is thrown when the model version property is missing
*/
String defaultDeserializeToVersion() default "";

/**
* @return class of the converter to use when resolving versioning to the current version; not specifying will cause
* models to not be converted at all
Expand All @@ -71,9 +77,4 @@
* @return name of property in which the model's version is stored in JSON
*/
String propertyName() default "modelVersion";

/**
* @return the default version to use if the propertyName() attribute is not available.
*/
String defaultDeserializeToVersion() default "";
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,7 @@ class VersionedModelDeserializer<T> extends StdDeserializer<T> implements Resolv
this.delegate = delegate;
this.jsonVersionedModel = jsonVersionedModel;
this.serializeToVersionProperty = serializeToVersionProperty;

if(serializeToVersionProperty != null) {
JsonSerializeToVersion annotatedJsonSerializeToVersion = serializeToVersionProperty.getAccessor().getAnnotation(JsonSerializeToVersion.class);

//Allow the field to be annotated and not just the accessor
if(annotatedJsonSerializeToVersion == null) {
annotatedJsonSerializeToVersion = serializeToVersionProperty.getField().getAnnotation(JsonSerializeToVersion.class);
}
this.serializeToVersionAnnotation = annotatedJsonSerializeToVersion;
} else {
this.serializeToVersionAnnotation = null;
}
this.serializeToVersionAnnotation = serializeToVersionProperty != null ? serializeToVersionProperty.getAccessor().getAnnotation(JsonSerializeToVersion.class) : null;

Class<? extends VersionedModelConverter> converterClass = jsonVersionedModel.toCurrentConverterClass();
if(converterClass != VersionedModelConverter.class)
Expand Down Expand Up @@ -88,15 +77,16 @@ public T deserialize(JsonParser parser, DeserializationContext context) throws I
ObjectNode modelData = (ObjectNode)jsonNode;

JsonNode modelVersionNode = modelData.remove(jsonVersionedModel.propertyName());
String modelVersion;
if(modelVersionNode == null) {
modelVersion = jsonVersionedModel.defaultDeserializeToVersion();
} else {

String modelVersion = null;
if(modelVersionNode != null)
modelVersion = modelVersionNode.asText();
}


if(modelVersion == null)
throw context.mappingException("'" + jsonVersionedModel.propertyName() + "' property was null");
modelVersion = jsonVersionedModel.defaultDeserializeToVersion();

if(modelVersion.isEmpty())
throw context.mappingException("'" + jsonVersionedModel.propertyName() + "' property was null and defaultDeserializeToVersion was not set");

// convert the model if converter specified and model needs converting
if(converter != null && (jsonVersionedModel.alwaysConvert() || !modelVersion.equals(jsonVersionedModel.currentVersion())))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,9 @@ private void doSerialize(T value, JsonGenerator generator, SerializerProvider pr
if(converter != null && (jsonVersionedModel.alwaysConvert() || !targetVersion.equals(jsonVersionedModel.currentVersion())))
modelData = converter.convert(modelData, jsonVersionedModel.currentVersion(), targetVersion, JsonNodeFactory.instance);

// add target version to model data if it wasn't the default
if(!targetVersion.equals(jsonVersionedModel.defaultDeserializeToVersion())) {
modelData.put(jsonVersionedModel.propertyName(), targetVersion);
}

// add target version to model data
modelData.put(jsonVersionedModel.propertyName(), targetVersion);

// write node
generator.writeTree(modelData);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
package com.github.jonpeterson.jackson.module.versioning;

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition;

Expand All @@ -34,9 +33,7 @@ public static BeanPropertyDefinition getSerializeToVersionProperty(BeanDescripti
BeanPropertyDefinition serializeToVersionProperty = null;
for(BeanPropertyDefinition definition: beanDescription.findProperties()) {
AnnotatedMember accessor = definition.getAccessor();
AnnotatedField field = definition.getField();

if((accessor != null && accessor.hasAnnotation(JsonSerializeToVersion.class)) || (field != null && field.hasAnnotation(JsonSerializeToVersion.class))) {
if(accessor != null && accessor.hasAnnotation(JsonSerializeToVersion.class)) {
if(serializeToVersionProperty != null)
throw new RuntimeException("@" + JsonSerializeToVersion.class.getSimpleName() + " must be present on at most one field or method");
if(accessor.getRawType() != String.class || (definition.getField() == null && !definition.hasGetter()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ package com.github.jonpeterson.jackson.module.versioning
import com.fasterxml.jackson.annotation.JsonIgnore
import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo
import com.fasterxml.jackson.databind.JsonMappingException
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.JsonNodeFactory
import com.fasterxml.jackson.databind.node.ObjectNode
Expand Down Expand Up @@ -58,6 +59,12 @@ class VersioningModuleTest extends Specification {
String _debugPreDeserializationVersion
}

@JsonVersionedModel(currentVersion = '3',
toCurrentConverterClass = ToCurrentCarConverter,
defaultDeserializeToVersion = '1')
static class DefaultDeserializeToCar extends Car {
}

@JsonVersionedModel(currentVersion = '3',
defaultSerializeToVersion = '2',
toCurrentConverterClass = ToCurrentCarConverter,
Expand Down Expand Up @@ -384,7 +391,7 @@ class VersioningModuleTest extends Specification {
}

@Unroll
def 'abc #clazz.simpleName'() {
def 'serialize with source version #clazz.simpleName'() {
when:
def car = mapper.readValue('{"model": "toyota:camry", "year": 2012, "new": "false", "_version": "1"}', clazz)
car.year = 2013
Expand All @@ -400,6 +407,31 @@ class VersioningModuleTest extends Specification {
SourceVersionMethodSerializeToCar | [_version: '1', model: 'toyota:camry', new: 'false', year: 2013, _debugPreDeserializationVersion: '1', _debugPreSerializationVersion: '3']
}

@Unroll
def 'missing version'() {
when: 'no version specified'
mapper.readValue('{"model": "toyota:camry", "year": 2012, "new": "false"}', Car)

then: 'throw exception since no defaultDeserializeToVersion on Car'
thrown JsonMappingException


when: 'no version specified'
def car = mapper.readValue('{"model": "toyota:camry", "year": 2012, "new": "false"}', DefaultDeserializeToCar)

then: 'treat it as version 1 as specified by defaultDeserializeToVersion on DefaultDeserializeToCar'
// using write->read instead of convert method due to Jackson 2.2 bug
mapper.readValue(mapper.writeValueAsString(car), Map) == [
make: 'toyota',
model: 'camry',
modelVersion: '3',
used: true,
year: 2012,
_debugPreDeserializationVersion: '1',
_debugPreSerializationVersion: null
]
}

def 'errors'() {
when:
mapper.writeValueAsString(clazz.newInstance())
Expand Down

0 comments on commit 9b45ada

Please sign in to comment.