From 123dfa820f977fd16fe1acadb9c23a179c5a77a4 Mon Sep 17 00:00:00 2001 From: Christian Gendreau Date: Tue, 25 Feb 2025 11:55:36 -0500 Subject: [PATCH] 35779 Move JsonApiModelBuilder related functions to its own class Added JsonApiModelBuilderHelper and moved related functions --- .../dina/repository/DinaRepositoryV2.java | 122 +-------------- .../repository/JsonApiModelBuilderHelper.java | 145 ++++++++++++++++++ 2 files changed, 149 insertions(+), 118 deletions(-) create mode 100644 dina-base-api/src/main/java/ca/gc/aafc/dina/repository/JsonApiModelBuilderHelper.java diff --git a/dina-base-api/src/main/java/ca/gc/aafc/dina/repository/DinaRepositoryV2.java b/dina-base-api/src/main/java/ca/gc/aafc/dina/repository/DinaRepositoryV2.java index 79a21c622..62fafab23 100644 --- a/dina-base-api/src/main/java/ca/gc/aafc/dina/repository/DinaRepositoryV2.java +++ b/dina-base-api/src/main/java/ca/gc/aafc/dina/repository/DinaRepositoryV2.java @@ -287,7 +287,8 @@ protected JsonApiModelBuilder createJsonApiModelBuilder(JsonApiDto jsonApiDto JsonApiModelBuilder mainBuilder = jsonApiModel(); - JsonApiModelBuilder builder = createJsonApiModelBuilder(jsonApiDto, mainBuilder, included); + JsonApiModelBuilder builder = JsonApiModelBuilderHelper. + createJsonApiModelBuilder(jsonApiDto, mainBuilder, included); JsonApiMeta.builder() .moduleVersion(buildProperties.getVersion()) .build() @@ -307,7 +308,8 @@ protected JsonApiModelBuilder createJsonApiModelBuilder(PagedResource> repModels = new ArrayList<>(); Set included = new HashSet<>(); for (JsonApiDto currResource : jsonApiDtos.resourceList()) { - JsonApiModelBuilder builder = createJsonApiModelBuilder(currResource, mainBuilder, included); + JsonApiModelBuilder builder = JsonApiModelBuilderHelper. + createJsonApiModelBuilder(currResource, mainBuilder, included); repModels.add(builder.build()); } @@ -323,122 +325,6 @@ protected JsonApiModelBuilder createJsonApiModelBuilder(PagedResource jsonApiDto, - JsonApiModelBuilder includeBuilder, - Set included) { - JsonApiModelBuilder builder = jsonApiModel().model(RepresentationModel.of(jsonApiDto.getDto())); - - for (var rel : jsonApiDto.getRelationships().entrySet()) { - switch (rel.getValue()) { - case JsonApiDto.RelationshipToOne toOne -> - setToOneOnJsonApiModelBuilder(builder, rel.getKey(), toOne, includeBuilder, included); - case JsonApiDto.RelationshipToMany toMany -> - setToManyOnJsonApiModelBuilder(builder, rel.getKey(), toMany, includeBuilder, included); - case JsonApiDto.RelationshipToOneExternal toOneExt -> - setToOneExtOnJsonApiModelBuilder(builder, rel.getKey(), toOneExt); - case JsonApiDto.RelationshipManyExternal toManyExt -> - setToManyExtOnJsonApiModelBuilder(builder, rel.getKey(), toManyExt); - default -> throw new IllegalStateException("Unexpected value: " + rel.getValue()); - } - } - return builder; - } - - /** - * Internal method to set {@link JsonApiDto.RelationshipToOne} to a {@link JsonApiModelBuilder}. - * @param builder current builder - * @param relationshipName - * @param toOne - * @param includeBuilder if null, builder will be used - * @param included set of already included uuid - */ - private static void setToOneOnJsonApiModelBuilder(JsonApiModelBuilder builder, String relationshipName, - JsonApiDto.RelationshipToOne toOne, - JsonApiModelBuilder includeBuilder, - Set included) { - - if (toOne.getIncluded() != null) { - builder.relationship(relationshipName, toOne.getIncluded()); - addUniqueIncluded(includeBuilder != null ? includeBuilder : builder, toOne.getIncluded(), included); - } else { - // requires spring-hateoas-jsonapi 2.x - // builder.relationship(relationshipName, (Object) null); - log.warn("Ignoring null value for toOne internal relationship {}", relationshipName); - } - } - - /** - * Internal method to set {@link JsonApiDto.RelationshipToMany} to a {@link JsonApiModelBuilder}. - * @param builder current builder - * @param relationshipName - * @param toMany - * @param includeBuilder if null, builder will be used - * @param included set of already included uuid - */ - private static void setToManyOnJsonApiModelBuilder(JsonApiModelBuilder builder, String relationshipName, - JsonApiDto.RelationshipToMany toMany, JsonApiModelBuilder includeBuilder,Set included) { - - if (toMany.getIncluded() != null) { - builder.relationship(relationshipName, toMany.getIncluded()); - for (var includedResource : toMany.getIncluded()) { - addUniqueIncluded(includeBuilder != null ? includeBuilder : builder, includedResource, included); - } - } else { - // requires spring-hateoas-jsonapi 2.x - // builder.relationship(relationshipName, (Object) null); - log.warn("Ignoring null value for toMany internal relationship {}", relationshipName); - } - } - - private static void setToOneExtOnJsonApiModelBuilder(JsonApiModelBuilder builder, String relationshipName, - JsonApiDto.RelationshipToOneExternal toOneExt) { - - if (toOneExt.getIncluded() != null) { - builder.relationship(relationshipName, toOneExt.getIncluded()); - // addUniqueIncluded(builder, toOneExt.getIncluded(), included); - } else { - //requires spring-hateoas-jsonapi 2.x - // builder.relationship(relationshipName, (Object) null); - log.warn("Ignoring null value for toOne external relationship {}", relationshipName); - } - } - - private static void setToManyExtOnJsonApiModelBuilder(JsonApiModelBuilder builder, String relationshipName, - JsonApiDto.RelationshipManyExternal toManyExt) { - if (toManyExt.getIncluded() != null) { - builder.relationship(relationshipName, toManyExt.getIncluded()); - } else { - //requires spring-hateoas-jsonapi 2.x - log.warn("Ignoring null value for toMany external relationship {}", relationshipName); - } - } - - /** - * Add an include {@link JsonApiResource} is not already present. - * The main goal of this method is to avoid duplicates in the include section. - * - * @param builder the current builder - * @param include the {@link JsonApiResource} to include - * @param included writable non-null set containing the already included uuid - */ - private static void addUniqueIncluded(JsonApiModelBuilder builder, - JsonApiResource include, Set included) { - Objects.requireNonNull(include); - - if (!included.contains(include.getJsonApiId())) { - builder.included(include); - included.add(include.getJsonApiId()); - } - } - /** * null-safe query string UTF-8 decode function. * @param req diff --git a/dina-base-api/src/main/java/ca/gc/aafc/dina/repository/JsonApiModelBuilderHelper.java b/dina-base-api/src/main/java/ca/gc/aafc/dina/repository/JsonApiModelBuilderHelper.java new file mode 100644 index 000000000..29ec70148 --- /dev/null +++ b/dina-base-api/src/main/java/ca/gc/aafc/dina/repository/JsonApiModelBuilderHelper.java @@ -0,0 +1,145 @@ +package ca.gc.aafc.dina.repository; + +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import lombok.extern.log4j.Log4j2; + +import org.springframework.hateoas.RepresentationModel; + +import com.toedter.spring.hateoas.jsonapi.JsonApiModelBuilder; + +import ca.gc.aafc.dina.dto.JsonApiDto; +import ca.gc.aafc.dina.dto.JsonApiResource; + +import static com.toedter.spring.hateoas.jsonapi.JsonApiModelBuilder.jsonApiModel; + +/** + * Utility class to assist with configuring {@link JsonApiModelBuilder} for {@link JsonApiDto}. + * The main focus is around relationships. + * + * Mostly supposed to be used by {@link DinaRepositoryV2} + */ +@Log4j2 +public final class JsonApiModelBuilderHelper { + + private JsonApiModelBuilderHelper () { + // utility class + } + + /** + * Internal(package protected) method to create {@link JsonApiModelBuilder}. + * @param jsonApiDto + * @param includeBuilder builder to use to add "included" documents. if null, the builder + * created for that document will be used. + * @param included set of already included uuid + * @return + */ + public static JsonApiModelBuilder createJsonApiModelBuilder(JsonApiDto jsonApiDto, + JsonApiModelBuilder includeBuilder, + Set included) { + JsonApiModelBuilder builder = jsonApiModel().model(RepresentationModel.of(jsonApiDto.getDto())); + + for (var rel : jsonApiDto.getRelationships().entrySet()) { + switch (rel.getValue()) { + case JsonApiDto.RelationshipToOne toOne -> + setToOneOnJsonApiModelBuilder(builder, rel.getKey(), toOne, includeBuilder, included); + case JsonApiDto.RelationshipToMany toMany -> + setToManyOnJsonApiModelBuilder(builder, rel.getKey(), toMany, includeBuilder, included); + case JsonApiDto.RelationshipToOneExternal toOneExt -> + setToOneExtOnJsonApiModelBuilder(builder, rel.getKey(), toOneExt); + case JsonApiDto.RelationshipManyExternal toManyExt -> + setToManyExtOnJsonApiModelBuilder(builder, rel.getKey(), toManyExt); + default -> throw new IllegalStateException("Unexpected value: " + rel.getValue()); + } + } + return builder; + } + + /** + * Internal method to set {@link JsonApiDto.RelationshipToOne} to a {@link JsonApiModelBuilder}. + * @param builder current builder + * @param relationshipName + * @param toOne + * @param includeBuilder if null, builder will be used + * @param included set of already included uuid + */ + private static void setToOneOnJsonApiModelBuilder(JsonApiModelBuilder builder, String relationshipName, + JsonApiDto.RelationshipToOne toOne, + JsonApiModelBuilder includeBuilder, + Set included) { + + if (toOne.getIncluded() != null) { + builder.relationship(relationshipName, toOne.getIncluded()); + addUniqueIncluded(includeBuilder != null ? includeBuilder : builder, toOne.getIncluded(), included); + } else { + // requires spring-hateoas-jsonapi 2.x + // builder.relationship(relationshipName, (Object) null); + log.warn("Ignoring null value for toOne internal relationship {}", relationshipName); + } + } + + /** + * Internal method to set {@link JsonApiDto.RelationshipToMany} to a {@link JsonApiModelBuilder}. + * @param builder current builder + * @param relationshipName + * @param toMany + * @param includeBuilder if null, builder will be used + * @param included set of already included uuid + */ + private static void setToManyOnJsonApiModelBuilder(JsonApiModelBuilder builder, String relationshipName, + JsonApiDto.RelationshipToMany toMany, JsonApiModelBuilder includeBuilder,Set included) { + + if (toMany.getIncluded() != null) { + builder.relationship(relationshipName, toMany.getIncluded()); + for (var includedResource : toMany.getIncluded()) { + addUniqueIncluded(includeBuilder != null ? includeBuilder : builder, includedResource, included); + } + } else { + // requires spring-hateoas-jsonapi 2.x + // builder.relationship(relationshipName, (Object) null); + log.warn("Ignoring null value for toMany internal relationship {}", relationshipName); + } + } + + private static void setToOneExtOnJsonApiModelBuilder(JsonApiModelBuilder builder, String relationshipName, + JsonApiDto.RelationshipToOneExternal toOneExt) { + + if (toOneExt.getIncluded() != null) { + builder.relationship(relationshipName, toOneExt.getIncluded()); + // addUniqueIncluded(builder, toOneExt.getIncluded(), included); + } else { + //requires spring-hateoas-jsonapi 2.x + // builder.relationship(relationshipName, (Object) null); + log.warn("Ignoring null value for toOne external relationship {}", relationshipName); + } + } + + private static void setToManyExtOnJsonApiModelBuilder(JsonApiModelBuilder builder, String relationshipName, + JsonApiDto.RelationshipManyExternal toManyExt) { + if (toManyExt.getIncluded() != null) { + builder.relationship(relationshipName, toManyExt.getIncluded()); + } else { + //requires spring-hateoas-jsonapi 2.x + log.warn("Ignoring null value for toMany external relationship {}", relationshipName); + } + } + + /** + * Add an include {@link JsonApiResource} is not already present. + * The main goal of this method is to avoid duplicates in the include section. + * + * @param builder the current builder + * @param include the {@link JsonApiResource} to include + * @param included writable non-null set containing the already included uuid + */ + private static void addUniqueIncluded(JsonApiModelBuilder builder, + JsonApiResource include, Set included) { + Objects.requireNonNull(include); + + if (!included.contains(include.getJsonApiId())) { + builder.included(include); + included.add(include.getJsonApiId()); + } + } +}