Skip to content

Commit

Permalink
Merge pull request #2 from infobip/SingleArgumentPropertiesCreatorMod…
Browse files Browse the repository at this point in the history
…eAnnotationIntrospector

added SingleArgumentPropertiesCreatorModeAnnotationIntrospector
  • Loading branch information
lpandzic authored Apr 16, 2021
2 parents 5de61b9 + 4aba117 commit 158495a
Show file tree
Hide file tree
Showing 16 changed files with 298 additions and 39 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
![](https://github.com/infobip/infobip-jackson-extension/workflows/maven/badge.svg)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.infobip/infobip-jackson-extension-spring-boot-starter/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.infobip/infobip-jackson-extension-spring-boot-starter)
[![Coverage Status](https://coveralls.io/repos/github/infobip/infobip-jackson-extension/badge.svg?branch=master)](https://coveralls.io/github/infobip/infobip-jackson-extension?branch=master)
[![Known Vulnerabilities](https://snyk.io/test/github/infobip/infobip-jackson-extension/badge.svg)](https://snyk.io/test/github/infobip/infobip-jackson-extension)

Library which provides new features for (de)serialization on top of [Jackson library](https://github.com/FasterXML/jackson).

Expand All @@ -16,6 +17,7 @@ Library which provides new features for (de)serialization on top of [Jackson lib
* [Multi level hierarchies](#MultiLevelHierarchies)
* [Parallel hierarchies](#ParallelHierarchies)
* [Typeless (present property)](#Typeless)
* [Single Argument Property Creator annotationless support](#SingleArgumentPropertyCreatorAnnotationlessSupport)

<a name="Setup"></a>
## Setup
Expand Down Expand Up @@ -245,6 +247,24 @@ Notice standard jackson `@JsonNaming` annotation in `Bike` interface.

[Showcase](infobip-jackson-extension-module/src/test/java/com/infobip/jackson/PresentPropertyCaseFormatDeserializerTest.java).

<a name="SingleArgumentPropertyCreatorAnnotationlessSupport"></a>
### Single Argument Property Creator annotationless support

This module also adds support for deserializing single property value objects when using parameter names module:

```java
class Foo {
private final Bar bar;

Foo(Bar bar) {
this.bar = bar;
}
}
```

without any additional configuration or annotations.
Related issues: https://github.com/FasterXML/jackson-databind/issues/1498, https://github.com/spring-projects/spring-boot/issues/26023.

## <a name="Requirements"></a> Requirements:

- Java 8
Expand Down
4 changes: 2 additions & 2 deletions infobip-jackson-extension-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
<version>30.1.1-jre</version>
</dependency>
</dependencies>
<artifactId>infobip-jackson-extension-api</artifactId>
</project>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ public class InfobipJacksonModule extends SimpleModule {
public void setupModule(SetupContext context) {
super.setupModule(context);
context.insertAnnotationIntrospector(new InfobipJacksonAnnotationIntrospector());
context.insertAnnotationIntrospector(new SingleArgumentPropertiesCreatorModeAnnotationIntrospector());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.infobip.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.*;

import java.lang.reflect.Field;
import java.lang.reflect.Parameter;
import java.util.Objects;
import java.util.stream.Stream;

public class SingleArgumentPropertiesCreatorModeAnnotationIntrospector extends NopAnnotationIntrospector {

@Override
public JsonCreator.Mode findCreatorAnnotation(MapperConfig<?> config, Annotated a) {
if (!(a instanceof AnnotatedConstructor)) {
return null;
}

AnnotatedConstructor annotatedConstructor = (AnnotatedConstructor) a;

if (annotatedConstructor.getParameterCount() != 1) {
return null;
}

Class<?> declaringClass = annotatedConstructor.getDeclaringClass();

if (declaringClass.getDeclaredConstructors().length > 1) {
return null;
}

if (doesntHaveMatchingFieldAndParameter(annotatedConstructor, declaringClass)) {
return null;
}

return JsonCreator.Mode.PROPERTIES;
}

private boolean doesntHaveMatchingFieldAndParameter(AnnotatedConstructor annotatedConstructor,
Class<?> declaringClass) {
Parameter parameter = annotatedConstructor.getAnnotated().getParameters()[0];
return Stream.of(declaringClass.getDeclaredFields())
.noneMatch(field -> doesFieldMatchParameter(field, parameter));
}

private boolean doesFieldMatchParameter(Field field, Parameter parameter) {

if(!field.getType().equals(parameter.getType())) {
return false;
}

String parameterName = parameter.getName();
JsonProperty annotation = field.getAnnotation(JsonProperty.class);

if (Objects.nonNull(annotation) && annotation.value().equals(parameterName)) {
return true;
}

return field.getName().equals(parameterName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,12 @@ interface FooBar extends SimpleJsonHierarchy<FooBarType> {
FooBarType getType();
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Foo implements FooBar {
private final String foo;
private final FooBarType type = FooBarType.FOO;
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Bar implements FooBar {
private final String bar;
Expand All @@ -132,4 +130,4 @@ enum FooBarType implements TypeProvider {

private final Class<? extends FooBar> type;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.infobip.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.*;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -48,14 +47,12 @@ public Class<?> resolve(Map<String, Object> json) {
}
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Foo extends FooBar {
private final String foo;
private final FooBarType type = FooBarType.FOO;
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Bar extends FooBar {
private final String bar;
Expand All @@ -70,4 +67,4 @@ enum FooBarType {

private final Class<? extends FooBar> type;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.infobip.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.*;
Expand Down Expand Up @@ -113,14 +112,12 @@ public Class<?> resolve(Map<String, Object> json) {
}
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Foo implements FooBar {
private final String foo;
private final FooBarType type = FooBarType.FOO;
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Bar implements FooBar {
private final String bar;
Expand All @@ -135,4 +132,4 @@ enum FooBarType {

private final Class<? extends FooBar> type;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.infobip.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
Expand Down Expand Up @@ -108,14 +107,12 @@ interface FooBar extends SimpleJsonHierarchy<FooBarType> {
FooBarType getType();
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Foo implements FooBar {
private final String foo;
private final FooBarType type = FooBarType.FOO;
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Bar implements FooBar {
private final String bar;
Expand All @@ -135,4 +132,4 @@ String getValue() {
return toString().toLowerCase();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.infobip.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.*;
Expand Down Expand Up @@ -123,7 +122,6 @@ public MammalJsonTypeResolver() {
}
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Human implements Mammal {
private final String name;
Expand All @@ -146,4 +144,4 @@ enum MammalType implements TypeProvider {

private final Class<? extends Mammal> type;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.infobip.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.*;
Expand Down Expand Up @@ -106,7 +105,6 @@ interface Animal extends SimpleJsonHierarchy<AnimalType> {
interface Mammal extends Animal {
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Human implements Mammal {
private final String name;
Expand All @@ -124,4 +122,4 @@ enum AnimalType implements TypeProvider {

private final Class<? extends Animal> type;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.infobip.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
Expand Down Expand Up @@ -117,14 +116,12 @@ public LowerUnderscorePresentPropertyJsonTypeResolver(Class<E> type) {
}
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class RoadBike implements Bike {

private final String roadBike;
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class MountainBike implements Bike {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.infobip.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.*;
Expand Down Expand Up @@ -103,14 +102,12 @@ interface Bike extends PresentPropertyJsonHierarchy<BikeType> {

}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class RoadBike implements Bike {

private final String roadBike;
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Bmx implements Bike {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.infobip.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.base.CaseFormat;
import lombok.*;
Expand Down Expand Up @@ -43,14 +42,12 @@ public BikeTypeResolver() {
}
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class RoadBike implements Bike {

private final String roadBike;
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class MountainBike implements Bike {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.infobip.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.*;
Expand Down Expand Up @@ -105,14 +104,12 @@ void shouldDeserializeFooAsFooFromJson() throws JsonProcessingException {
interface FooBar extends SimpleJsonHierarchy<FooBarType> {
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Foo implements FooBar {
private final String foo;
private final FooBarType type = FooBarType.FOO;
}

@AllArgsConstructor(onConstructor_ = @JsonCreator)
@Value
static class Bar implements FooBar {
private final String bar;
Expand All @@ -127,4 +124,4 @@ enum FooBarType implements TypeProvider {

private final Class<? extends FooBar> type;
}
}
}
Loading

0 comments on commit 158495a

Please sign in to comment.