This repository has been archived by the owner on May 26, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #26 from CJSCommonPlatform/fix-integer-enum
Add Integer based enum capability for serialisation and deserialization of Json
- Loading branch information
Showing
13 changed files
with
553 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
...ain/java/uk/gov/justice/services/common/converter/jackson/integerenum/EnumObjectUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package uk.gov.justice.services.common.converter.jackson.integerenum; | ||
|
||
import static java.util.Optional.empty; | ||
import static java.util.Optional.of; | ||
|
||
import java.io.Serializable; | ||
import java.lang.reflect.Field; | ||
import java.util.Optional; | ||
|
||
import com.fasterxml.jackson.databind.JsonMappingException; | ||
import com.fasterxml.jackson.databind.SerializerProvider; | ||
|
||
public class EnumObjectUtil implements Serializable { | ||
|
||
private static final long serialVersionUID = -7399009049859936180L; | ||
|
||
public Optional<Object> findEnumObject(final Object enumObject, final int enumValue) { | ||
final Field[] declaredFields = enumObject.getClass().getDeclaredFields(); | ||
|
||
for (final Field field : declaredFields) { | ||
if (isIntegerFieldType(field)) { | ||
try { | ||
field.setAccessible(true); | ||
final int fieldValue = (int) field.get(enumObject); | ||
if (fieldValue == enumValue) { | ||
return of(enumObject); | ||
} | ||
} catch (final IllegalAccessException e) { | ||
//Do nothing | ||
} | ||
} | ||
} | ||
return empty(); | ||
} | ||
|
||
public Optional<Integer> integerValueFromFieldOfEnum(final Enum<?> enumObject, | ||
final String fieldName, | ||
final SerializerProvider serializerProvider) throws JsonMappingException { | ||
try { | ||
final Field field = enumObject.getClass().getDeclaredField(fieldName); | ||
field.setAccessible(true); | ||
return Optional.of((Integer) field.get(enumObject)); | ||
} catch (NoSuchFieldException | IllegalAccessException ex) { | ||
throw serializerProvider.mappingException("Could not serialize enum object", ex); | ||
} | ||
} | ||
|
||
public Optional<String> integerFieldNameFrom(final Enum<?> enumObject) { | ||
final Field[] fields = enumObject.getClass().getDeclaredFields(); | ||
|
||
for (final Field field : fields) { | ||
if (isIntegerFieldType(field)) { | ||
return Optional.of(field.getName()); | ||
} | ||
} | ||
|
||
return empty(); | ||
} | ||
|
||
private boolean isIntegerFieldType(final Field field) { | ||
return Integer.class.isAssignableFrom(field.getType()); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
...ce/services/common/converter/jackson/integerenum/IntegerEnumBeanDeserializerModifier.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package uk.gov.justice.services.common.converter.jackson.integerenum; | ||
|
||
import static com.fasterxml.jackson.databind.AnnotationIntrospector.nopInstance; | ||
import static com.fasterxml.jackson.databind.util.EnumResolver.constructFor; | ||
|
||
import com.fasterxml.jackson.databind.BeanDescription; | ||
import com.fasterxml.jackson.databind.DeserializationConfig; | ||
import com.fasterxml.jackson.databind.JavaType; | ||
import com.fasterxml.jackson.databind.JsonDeserializer; | ||
import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier; | ||
import com.fasterxml.jackson.databind.util.EnumResolver; | ||
|
||
public class IntegerEnumBeanDeserializerModifier extends BeanDeserializerModifier { | ||
|
||
@SuppressWarnings("unchecked") | ||
@Override | ||
public JsonDeserializer<?> modifyEnumDeserializer( | ||
final DeserializationConfig config, | ||
final JavaType type, | ||
final BeanDescription beanDesc, | ||
final JsonDeserializer<?> deserializer) { | ||
|
||
final Class<Enum<?>> enumClass = (Class<Enum<?>>) type.getRawClass(); | ||
|
||
final EnumResolver enumResolver = constructFor(enumClass, nopInstance()); | ||
|
||
return new IntegerEnumDeserializer( | ||
enumResolver, | ||
new EnumObjectUtil()); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
...tice/services/common/converter/jackson/integerenum/IntegerEnumBeanSerializerModifier.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package uk.gov.justice.services.common.converter.jackson.integerenum; | ||
|
||
import static java.util.Arrays.stream; | ||
|
||
import java.lang.reflect.Field; | ||
import java.util.Optional; | ||
|
||
import com.fasterxml.jackson.databind.BeanDescription; | ||
import com.fasterxml.jackson.databind.JavaType; | ||
import com.fasterxml.jackson.databind.JsonSerializer; | ||
import com.fasterxml.jackson.databind.SerializationConfig; | ||
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; | ||
import com.fasterxml.jackson.databind.ser.std.EnumSerializer; | ||
import com.fasterxml.jackson.databind.util.EnumValues; | ||
|
||
|
||
public class IntegerEnumBeanSerializerModifier extends BeanSerializerModifier { | ||
|
||
@Override | ||
public JsonSerializer<?> modifyEnumSerializer(final SerializationConfig config, | ||
final JavaType valueType, | ||
final BeanDescription beanDesc, | ||
final JsonSerializer<?> serializer) { | ||
|
||
final EnumValues enumValues = ((EnumSerializer) serializer).getEnumValues(); | ||
final Optional integerEnum = isIntegerEnum(enumValues); | ||
|
||
if (integerEnum.isPresent()) { | ||
return new IntegerEnumSerializer( | ||
enumValues.getEnumClass(), | ||
new EnumObjectUtil()); | ||
} | ||
return super.modifySerializer(config, beanDesc, serializer); | ||
} | ||
|
||
private Optional isIntegerEnum(final EnumValues enumValues) { | ||
final Class<Enum<?>> enumClass = enumValues.getEnumClass(); | ||
|
||
final Field[] declaredFields = enumClass.getDeclaredFields(); | ||
|
||
return stream(declaredFields) | ||
.filter(field -> Integer.class.isAssignableFrom(field.getType())) | ||
.findFirst(); | ||
} | ||
|
||
} |
48 changes: 48 additions & 0 deletions
48
...uk/gov/justice/services/common/converter/jackson/integerenum/IntegerEnumDeserializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package uk.gov.justice.services.common.converter.jackson.integerenum; | ||
|
||
import static java.util.Arrays.asList; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
import java.util.Optional; | ||
|
||
import com.fasterxml.jackson.core.JsonParser; | ||
import com.fasterxml.jackson.core.JsonToken; | ||
import com.fasterxml.jackson.databind.DeserializationContext; | ||
import com.fasterxml.jackson.databind.deser.std.EnumDeserializer; | ||
import com.fasterxml.jackson.databind.util.EnumResolver; | ||
|
||
public class IntegerEnumDeserializer extends EnumDeserializer { | ||
|
||
private static final long serialVersionUID = 1L; | ||
|
||
private final List<Enum<?>> enumerations; | ||
private final EnumObjectUtil enumObjectUtil; | ||
|
||
public IntegerEnumDeserializer(final EnumResolver enumResolver, | ||
final EnumObjectUtil enumObjectUtil) { | ||
super(enumResolver); | ||
this.enumerations = asList(enumResolver.getRawEnums()); | ||
this.enumObjectUtil = enumObjectUtil; | ||
} | ||
|
||
@Override | ||
public Object deserialize(final JsonParser jsonParser, final DeserializationContext context) throws IOException { | ||
|
||
if (jsonParser.getCurrentToken() == JsonToken.VALUE_NUMBER_INT) { | ||
|
||
final int enumValue = jsonParser.getIntValue(); | ||
|
||
for (final Object enumObject : enumerations) { | ||
|
||
final Optional<Object> enumerationFound = enumObjectUtil.findEnumObject(enumObject, enumValue); | ||
|
||
if (enumerationFound.isPresent()) { | ||
return enumerationFound.get(); | ||
} | ||
} | ||
} | ||
|
||
return super.deserialize(jsonParser, context); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
.../java/uk/gov/justice/services/common/converter/jackson/integerenum/IntegerEnumModule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package uk.gov.justice.services.common.converter.jackson.integerenum; | ||
|
||
import com.fasterxml.jackson.databind.module.SimpleModule; | ||
|
||
public class IntegerEnumModule extends SimpleModule { | ||
|
||
@Override | ||
public void setupModule(final SetupContext context) { | ||
super.setupModule(context); | ||
context.addBeanSerializerModifier(new IntegerEnumBeanSerializerModifier()); | ||
context.addBeanDeserializerModifier(new IntegerEnumBeanDeserializerModifier()); | ||
} | ||
|
||
} |
42 changes: 42 additions & 0 deletions
42
...a/uk/gov/justice/services/common/converter/jackson/integerenum/IntegerEnumSerializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package uk.gov.justice.services.common.converter.jackson.integerenum; | ||
|
||
import static java.util.Optional.empty; | ||
|
||
import java.io.IOException; | ||
import java.util.Optional; | ||
|
||
import com.fasterxml.jackson.core.JsonGenerator; | ||
import com.fasterxml.jackson.databind.SerializerProvider; | ||
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer; | ||
|
||
public class IntegerEnumSerializer extends StdScalarSerializer<Enum<?>> { | ||
|
||
private static final long serialVersionUID = 1L; | ||
|
||
private final EnumObjectUtil enumObjectUtil; | ||
|
||
public IntegerEnumSerializer(final Class<?> enumClass, final EnumObjectUtil enumObjectUtil) { | ||
super(enumClass, false); | ||
this.enumObjectUtil = enumObjectUtil; | ||
} | ||
|
||
@Override | ||
public void serialize(final Enum<?> enumeration, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException { | ||
final Optional<Integer> enumValue = getIntegerValue(enumeration, serializerProvider); | ||
|
||
if (enumValue.isPresent()) { | ||
jsonGenerator.writeNumber(enumValue.get()); | ||
} | ||
} | ||
|
||
private Optional<Integer> getIntegerValue(final Enum<?> enumObject, final SerializerProvider serializerProvider) throws IOException { | ||
final Optional<String> fieldName = enumObjectUtil.integerFieldNameFrom(enumObject); | ||
|
||
if (fieldName.isPresent()) { | ||
return enumObjectUtil.integerValueFromFieldOfEnum(enumObject, fieldName.get(), serializerProvider); | ||
} | ||
|
||
return empty(); | ||
} | ||
} | ||
|
Oops, something went wrong.