Skip to content

Commit

Permalink
3.0.24 - Deserializer for ResourceModel
Browse files Browse the repository at this point in the history
  • Loading branch information
saw303 committed Sep 1, 2023
1 parent 91b0049 commit e7e98ff
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 8 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ plugins {

subprojects { subproject ->

version = "3.0.23"
version = "3.0.24"

apply plugin: 'com.github.ben-manes.versions'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class RestApiPlugin implements Plugin<Project> {

project.configurations.maybeCreate(CONFIGURATION_REST_API)

final String pluginVersion = "3.0.23"
final String pluginVersion = "3.0.24"
final String libPhoneNumberVersion = "8.11.5"

final List<String> deps = [
Expand Down
1 change: 1 addition & 0 deletions gradle/micronaut.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ micronaut {

dependencies {
annotationProcessor("io.micronaut.serde:micronaut-serde-processor")
testAnnotationProcessor("io.micronaut.serde:micronaut-serde-processor")
implementation("io.micronaut.serde:micronaut-serde-jackson")
runtimeOnly("ch.qos.logback:logback-classic")
testImplementation("io.micronaut:micronaut-http-client")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
package ch.silviowangler.rest.model;

import io.micronaut.serde.annotation.Serdeable;
import java.util.Collection;
import java.util.List;

/**
Expand All @@ -37,15 +36,15 @@
public class Expand {

private String name;
private List<ResourceModel> data;
private List<? extends ResourceModel> data;

public Expand() {}

public Expand(String name) {
this.name = name;
}

public Expand(String name, List<ResourceModel> data) {
public Expand(String name, List<? extends ResourceModel> data) {
this.name = name;
this.data = data;
}
Expand All @@ -58,11 +57,11 @@ public void setName(String name) {
this.name = name;
}

public Collection<ResourceModel> getData() {
public List<? extends ResourceModel> getData() {
return data;
}

public void setData(List<ResourceModel> data) {
public void setData(List<? extends ResourceModel> data) {
this.data = data;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
*/
package ch.silviowangler.rest.model;

import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id.CLASS;

import com.fasterxml.jackson.annotation.JsonTypeInfo;

/**
* A simple marker interface for resource models.
*
* @author Silvio Wangler
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
@JsonTypeInfo(use = CLASS)
public interface ResourceModel {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* MIT License
* <p>
* Copyright (c) 2016 - 2023 Silvio Wangler (silvio.wangler@gmail.com)
* <p>
* 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:
* <p>
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* <p>
* 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 ch.silviowangler.rest.serdes;

import ch.silviowangler.rest.model.ResourceModel;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.micronaut.context.annotation.Secondary;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.beans.BeanIntrospection;
import io.micronaut.core.type.Argument;
import io.micronaut.json.tree.JsonNode;
import io.micronaut.serde.Decoder;
import io.micronaut.serde.Deserializer;
import jakarta.inject.Singleton;
import java.io.IOException;

@Singleton
@Secondary
public class ResourceModelDeserializer implements Deserializer<ResourceModel> {
@Override
public @Nullable ResourceModel deserialize(
@NonNull Decoder decoder,
@NonNull DecoderContext context,
@NonNull Argument<? super ResourceModel> type)
throws IOException {

JsonNode jsonNode = decoder.decodeNode();
JsonNode classValue = jsonNode.get(JsonTypeInfo.Id.CLASS.getDefaultPropertyName());

try {
Class<ResourceModel> clazz =
(Class<ResourceModel>) Class.forName(classValue.getStringValue());
BeanIntrospection<ResourceModel> introspection = BeanIntrospection.getIntrospection(clazz);

ResourceModel resourceModel = introspection.instantiate();
introspection
.getBeanProperties()
.forEach(
beanProperty ->
beanProperty.set(
resourceModel,
context
.getConversionService()
.convert(
jsonNode.get(beanProperty.getName()).getValue(),
beanProperty.getType())
.orElseThrow()));

return resourceModel;

} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package ch.silviowangler.rest.validation

import ch.silviowangler.rest.model.Expand
import io.micronaut.serde.ObjectMapper
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import spock.lang.Shared
import spock.lang.Specification

import java.time.LocalDate

@MicronautTest
class ExpandSerdeSpec extends Specification {

@Inject
ObjectMapper objectMapper

@Shared
final Expand expand = new Expand("aaa", [new ActivitiesGetResourceModel(id: 'hh', key: 'hhh', number: 12, dob: LocalDate.of(1978, 11, 1))])

void "Serialize Expand"() {

expect:
objectMapper.writeValueAsString(expand) == '{"name":"aaa","data":[{"@class":"ch.silviowangler.rest.validation.ActivitiesGetResourceModel","key":"hhh","id":"hh","number":12,"dob":"1978-11-01"}]}'
}


void "Deserialize Expand"() {

given:
final String json = objectMapper.writeValueAsString(expand)

when:
Expand result = objectMapper.readValue(json, Expand)

then:
result.name == expand.name

and:
result.data.size() == 1

and:
with(result.data.first()) { ActivitiesGetResourceModel res ->
res.id == 'hh'
res.key == 'hhh'
res.number == 12
res.dob == LocalDate.of(1978, 11, 1)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* MIT License
* <p>
* Copyright (c) 2016 - 2023 Silvio Wangler (silvio.wangler@gmail.com)
* <p>
* 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:
* <p>
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* <p>
* 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 ch.silviowangler.rest.validation;

import ch.silviowangler.rest.model.ResourceModel;
import io.micronaut.serde.annotation.Serdeable;
import java.time.LocalDate;

@Serdeable
public class ActivitiesGetResourceModel implements ResourceModel {
private String key;
private String id;
private Integer number;
private LocalDate dob;

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public Integer getNumber() {
return number;
}

public void setNumber(Integer number) {
this.number = number;
}

public LocalDate getDob() {
return dob;
}

public void setDob(LocalDate dob) {
this.dob = dob;
}
}

0 comments on commit e7e98ff

Please sign in to comment.