Skip to content

Commit

Permalink
Overhauled and added documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
jonpeterson committed Aug 1, 2016
1 parent d1f9f9c commit 0fb4d96
Show file tree
Hide file tree
Showing 14 changed files with 396 additions and 138 deletions.
12 changes: 3 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,13 @@ buildscript {
ext {
// external dependency versions
groovyVersion = '2.4.5'
gradleVersion = '2.9'
jacksonVersion = '2.6.7'
slf4jVersion = '1.7.12'
gradleVersion = '2.14.1'
jacksonVersion = '[2.2,)'
spockVersion = '1.0-groovy-2.4'

// external dependencies
groovy = "org.codehaus.groovy:groovy-all:${groovyVersion}"
jacksonDatabind = "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}"
slf4jApi = "org.slf4j:slf4j-api:${slf4jVersion}"
slf4jSimple = "org.slf4j:slf4j-simple:${slf4jVersion}"
spockCore = "org.spockframework:spock-core:${spockVersion}"
}

Expand All @@ -22,12 +19,11 @@ buildscript {


task wrapper(type: Wrapper) {
gradleVersion = gradleVersion
gradleVersion = this.gradleVersion
}


group = 'com.github.jonpeterson'
version = '1.0.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'groovy'
Expand All @@ -41,9 +37,7 @@ repositories {

dependencies {
compile jacksonDatabind
compile slf4jApi

testCompile groovy
testCompile slf4jSimple
testCompile spockCore
}
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version=1.0.0-SNAPSHOT
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Thu Jul 28 10:56:21 EDT 2016
#Sun Jul 31 02:03:03 EDT 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
46 changes: 25 additions & 21 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,30 @@
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

Expand All @@ -30,6 +48,7 @@ die ( ) {
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
Expand All @@ -40,26 +59,11 @@ case "`uname`" in
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
Expand All @@ -85,7 +89,7 @@ location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
Expand Down
8 changes: 4 additions & 4 deletions gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

Expand Down Expand Up @@ -46,7 +46,7 @@ echo location of your Java installation.
goto fail

:init
@rem Get command-line arguments, handling Windowz variants
@rem Get command-line arguments, handling Windows variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016 Jon Peterson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package com.github.jonpeterson.jackson.module.versioning;

import com.fasterxml.jackson.annotation.JacksonAnnotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Specifies converter for used in resolving versioning for pre-deserialized JSON.
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonVersionedModel {

/**
* @return the current version of the model; this will be added to the serialized model's {@link #propertyName()}.
*/
String currentVersion();

/**
* @return class of the converter to use when resolving versioning.
*/
Class<? extends VersionedModelConverter> converterClass();

/**
* @return whether to always send JSON data to converter, even when the data is the same version as the
* {@link #currentVersion()}.
*/
boolean alwaysConvert() default false;

/**
* @return name of property in which the model's version is stored in JSON.
*/
String propertyName() default "modelVersion";
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.github.jonpeterson.jackson.module.versioning;

import com.fasterxml.jackson.databind.node.ObjectNode;

/**
* Converter used by {@link JsonVersionedModel} for resolving model versioning.
*/
public interface VersionedModelConverter {

/**
* Updates JSON data before deserialization to model.
*
* @param modelVersion version of data
* @param modelData JSON data to update
*/
void convert(String modelVersion, ObjectNode modelData);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,59 +1,62 @@
package com.github.jonpeterson.jackson.module.versioning;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.ResolvableDeserializer;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TreeTraversingParser;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;

public class VersionedModelDeserializer extends StdDeserializer<VersionedModel> implements ResolvableDeserializer {
private final JsonDeserializer<VersionedModel> delegateDeserializer;
private final VersionedModelDataTransformer transformer;
class VersionedModelDeserializer<T> extends StdDeserializer<T> implements ResolvableDeserializer {
private final StdDeserializer<T> delegate;
private final JsonVersionedModel jsonVersionedModel;
private final VersionedModelConverter converter;

protected VersionedModelDeserializer(JsonDeserializer<VersionedModel> delegateDeserializer, VersionedModelDataTransformer transformer) {
super(VersionedModel.class);
VersionedModelDeserializer(StdDeserializer<T> delegate, JsonVersionedModel jsonVersionedModel) {
super(delegate.getValueType());

this.delegateDeserializer = delegateDeserializer;
this.transformer = transformer;
this.delegate = delegate;
this.jsonVersionedModel = jsonVersionedModel;

try {
this.converter = jsonVersionedModel.converterClass().newInstance();
} catch(Exception e) {
throw new RuntimeException("unable to create instance of converter '" + jsonVersionedModel.converterClass().getName() + "'", e);
}
}

@Override
public void resolve(DeserializationContext context) throws JsonMappingException {
((ResolvableDeserializer)delegateDeserializer).resolve(context);
if(delegate instanceof ResolvableDeserializer)
((ResolvableDeserializer)delegate).resolve(context);
}

@Override
public VersionedModel deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
TreeNode treeNode = parser.readValueAsTree();
public T deserialize(JsonParser parser, DeserializationContext context) throws IOException {
JsonNode jsonNode = parser.readValueAsTree();

if(!(treeNode instanceof ObjectNode))
if(!(jsonNode instanceof ObjectNode))
throw context.mappingException("value must be a JSON object");

ObjectNode objectNode = (ObjectNode)treeNode;
ObjectNode modelData = (ObjectNode)jsonNode;

JsonNode modelVersionNode = objectNode.remove(VersionedModel.MODEL_VERSION_PROPERTY);
JsonNode modelVersionNode = modelData.remove(jsonVersionedModel.propertyName());
if(modelVersionNode == null)
throw context.mappingException("'" + VersionedModel.MODEL_VERSION_PROPERTY + "' property was not present");

// DEBUG HERE
//Class<?> abc = delegateDeserializer.handledType();
//((ParameterizedType)abc.getGenericInterfaces()[0]).getActualTypeArguments()[0]
throw context.mappingException("'" + jsonVersionedModel.propertyName() + "' property was not present");

String modelVersion = modelVersionNode.asText();
if(modelVersion == null)
throw context.mappingException("'" + VersionedModel.MODEL_VERSION_PROPERTY + "' property was null");
throw context.mappingException("'" + jsonVersionedModel.propertyName() + "' property was null");

if(transformer != null && !modelVersion.equals(transformer.targetVersion))
transformer.transform(modelVersion, objectNode);
if(jsonVersionedModel.alwaysConvert() || !modelVersion.equals(jsonVersionedModel.currentVersion()))
converter.convert(modelVersion, modelData);

JsonParser objectNodeParser = new TreeTraversingParser(objectNode);
objectNodeParser.nextToken();
return delegateDeserializer.deserialize(objectNodeParser, context);
JsonParser postInterceptionParser = new TreeTraversingParser(jsonNode, parser.getCodec());
postInterceptionParser.nextToken();
return delegate.deserialize(postInterceptionParser, context);
}
}
}
Loading

0 comments on commit 0fb4d96

Please sign in to comment.