diff --git a/src/main/java/org/folio/linked/data/mapper/dto/common/SingleResourceMapperUnit.java b/src/main/java/org/folio/linked/data/mapper/dto/common/SingleResourceMapperUnit.java index 8959508d..9a3bad3d 100644 --- a/src/main/java/org/folio/linked/data/mapper/dto/common/SingleResourceMapperUnit.java +++ b/src/main/java/org/folio/linked/data/mapper/dto/common/SingleResourceMapperUnit.java @@ -1,5 +1,9 @@ package org.folio.linked.data.mapper.dto.common; +import static java.util.Optional.ofNullable; +import static org.folio.ld.dictionary.PropertyDictionary.RESOURCE_PREFERRED; + +import com.fasterxml.jackson.databind.JsonNode; import java.util.Set; import org.folio.linked.data.model.entity.Resource; @@ -11,4 +15,12 @@ public interface SingleResourceMapperUnit { Set> supportedParents(); + default boolean isPreferred(Resource resource) { + return ofNullable(resource.getDoc()) + .map(doc -> doc.get(RESOURCE_PREFERRED.getValue())) + .map(jsonNode -> jsonNode.get(0)) + .map(JsonNode::asBoolean) + .orElse(false); + } + } diff --git a/src/main/java/org/folio/linked/data/mapper/dto/monograph/work/sub/AgentMapperUnit.java b/src/main/java/org/folio/linked/data/mapper/dto/monograph/work/sub/AgentMapperUnit.java index e24c01eb..1e1a2c2c 100644 --- a/src/main/java/org/folio/linked/data/mapper/dto/monograph/work/sub/AgentMapperUnit.java +++ b/src/main/java/org/folio/linked/data/mapper/dto/monograph/work/sub/AgentMapperUnit.java @@ -24,7 +24,8 @@ public

P toDto(Resource source, P parentDto, Resource parentResource) { var agent = new Agent() .id(String.valueOf(source.getId())) .label(source.getLabel()) - .type(source.getTypes().iterator().next().getUri()); + .type(source.getTypes().iterator().next().getUri()) + .isPreferred(isPreferred(source)); agentRoleAssigner.assignRoles(agent, parentResource); agentConsumer.accept(parentDto, agent); return parentDto; diff --git a/src/main/java/org/folio/linked/data/mapper/dto/monograph/work/sub/ReferenceMapperUnit.java b/src/main/java/org/folio/linked/data/mapper/dto/monograph/work/sub/ReferenceMapperUnit.java index e7ea1deb..58836ccc 100644 --- a/src/main/java/org/folio/linked/data/mapper/dto/monograph/work/sub/ReferenceMapperUnit.java +++ b/src/main/java/org/folio/linked/data/mapper/dto/monograph/work/sub/ReferenceMapperUnit.java @@ -19,7 +19,8 @@ public

P toDto(Resource source, P parentDto, Resource parentResource) { source = ensureLatestReplaced(source); var reference = new Reference() .id(String.valueOf(source.getId())) - .label(source.getLabel()); + .label(source.getLabel()) + .isPreferred(isPreferred(source)); referenceConsumer.accept(reference, parentDto); return parentDto; } diff --git a/src/main/resources/swagger.api/schema/resource/common/Reference.json b/src/main/resources/swagger.api/schema/resource/common/Reference.json index 7f2be199..d26423fc 100644 --- a/src/main/resources/swagger.api/schema/resource/common/Reference.json +++ b/src/main/resources/swagger.api/schema/resource/common/Reference.json @@ -14,6 +14,10 @@ "srsId": { "type": "string", "description": "SRS ID of the resource" + }, + "isPreferred": { + "type": "boolean", + "description": "Indicates whether resource is controlled or not" } } } diff --git a/src/test/java/org/folio/linked/data/e2e/resource/ResourceControllerITBase.java b/src/test/java/org/folio/linked/data/e2e/resource/ResourceControllerITBase.java index fdac7a03..7d6d6282 100644 --- a/src/test/java/org/folio/linked/data/e2e/resource/ResourceControllerITBase.java +++ b/src/test/java/org/folio/linked/data/e2e/resource/ResourceControllerITBase.java @@ -204,6 +204,7 @@ public abstract class ResourceControllerITBase { private static final String NOTES_PROPERTY = "_notes"; private static final String ID_PROPERTY = "id"; private static final String LABEL_PROPERTY = "label"; + private static final String IS_PREFERRED_PROPERTY = "isPreferred"; private static final String VALUE_PROPERTY = "value"; private static final String TYPE_PROPERTY = "type"; private static final String INSTANCE_REF = "_instanceReference"; @@ -712,6 +713,7 @@ void getWorkById_shouldReturnWorkWithInstanceRef() throws Exception { .andExpect(content().contentType(APPLICATION_JSON)) .andReturn().getResponse().getContentAsString(); validateWorkResponse(resultActions, toWork()); + validateAuthorities(resultActions, toWork()); } @ParameterizedTest @@ -1050,7 +1052,7 @@ private void validateWorkResponse(ResultActions resultActions, String workBase) .andExpect(jsonPath(toWorkContentLink(workBase), equalTo("http://id.loc.gov/vocabulary/contentTypes/txt"))) .andExpect(jsonPath(toWorkContentCode(workBase), equalTo("txt"))) .andExpect(jsonPath(toWorkContentTerm(workBase), equalTo("text"))) - .andExpect(jsonPath(toWorkSubjectLabel(workBase), equalTo(List.of("subject 1", "subject 2")))) + .andExpect(jsonPath(toWorkSubjectLabel(workBase), containsInAnyOrder("subject 1", "subject 2"))) .andExpect(jsonPath(toWorkSummary(workBase), equalTo("summary text"))) .andExpect(jsonPath(toWorkTableOfContents(workBase), equalTo("table of contents"))) .andExpect(jsonPath(toWorkNotesValues(workBase), @@ -1074,6 +1076,14 @@ private void validateWorkResponse(ResultActions resultActions, String workBase) } } + private void validateAuthorities(ResultActions resultActions, String workBase) throws Exception { + resultActions + .andExpect(jsonPath(toWorkCreatorIsPreferred(workBase), containsInAnyOrder(true, false, false, false))) + .andExpect(jsonPath(toWorkContributorIsPreferred(workBase), containsInAnyOrder(true, false, false, false))) + .andExpect(jsonPath(toWorkSubjectIsPreferred(workBase), containsInAnyOrder(true, false))) + .andExpect(jsonPath(toWorkGenreIsPreferred(workBase), containsInAnyOrder(true, false))); + } + private void validateInstance(Resource instance, boolean validateFullWork) { assertThat(instance.getId()).isEqualTo(hashService.hash(instance)); assertThat(instance.getLabel()).isEqualTo("Primary: mainTitle"); @@ -1453,8 +1463,8 @@ private void validateWork(Resource work, boolean validateFullInstance) { validateWorkContributor(outgoingEdgeIterator.next(), work, PERSON, CREATOR); validateWorkContributor(outgoingEdgeIterator.next(), work, PERSON, CONTRIBUTOR); validateVariantTitle(outgoingEdgeIterator.next(), work); - validateResourceEdge(outgoingEdgeIterator.next(), work, lookupResources.subjects().get(0), SUBJECT.getUri()); validateResourceEdge(outgoingEdgeIterator.next(), work, lookupResources.subjects().get(1), SUBJECT.getUri()); + validateResourceEdge(outgoingEdgeIterator.next(), work, lookupResources.subjects().get(0), SUBJECT.getUri()); validateResourceEdge(outgoingEdgeIterator.next(), work, lookupResources.genres().get(0), GENRE.getUri()); validateResourceEdge(outgoingEdgeIterator.next(), work, lookupResources.genres().get(1), GENRE.getUri()); validateOriginPlace(outgoingEdgeIterator.next(), work); @@ -1564,7 +1574,6 @@ private void validateWorkContributor(ResourceEdge edge, Resource source, Resourc assertThat(creator.getId()).isEqualTo(hashService.hash(creator)); var types = creator.getTypes().stream().map(ResourceTypeEntity::getUri).toList(); assertThat(types).contains(type.getUri()); - assertThat(creator.getDoc().size()).isEqualTo(2); assertThat(creator.getDoc().get(NAME.getValue()).size()).isEqualTo(1); assertThat(creator.getDoc().get(NAME.getValue()).get(0).asText()).isEqualTo("name-" + predicate + "-" + type); assertThat(creator.getDoc().get(LCNAF_ID.getValue()).size()).isEqualTo(1); @@ -1658,8 +1667,8 @@ private void validateCopyrightDate(ResourceEdge edge, Resource source) { } private LookupResources saveLookupResources() { - var subject1 = saveResource(-2609581195837993519L, "subject 1", CONCEPT, - "{\"http://bibfra.me/vocab/lite/name\": [\"Subject 1\"]}"); + var subject1 = saveResource(5116157127128345626L, "subject 1", CONCEPT, + "{\"http://bibfra.me/vocab/lite/name\": [\"Subject 1\"], \"http://library.link/vocab/resourcePreferred\":[\"true\"]}"); var subject2 = saveResource(-643516859818423084L, "subject 2", CONCEPT, "{\"http://bibfra.me/vocab/lite/name\": [\"Subject 2\"]}"); var unitedStates = saveResource(7109832602847218134L, "United States", PLACE, @@ -2131,6 +2140,10 @@ private String toWorkCreatorRoles(String workBase) { return join(".", workBase, dynamicArrayPath(CREATOR_REF), path(ROLES_PROPERTY)); } + private String toWorkCreatorIsPreferred(String workBase) { + return join(".", workBase, dynamicArrayPath(CREATOR_REF), path(IS_PREFERRED_PROPERTY)); + } + private String toWorkContributorId(String workBase) { return join(".", workBase, dynamicArrayPath(CONTRIBUTOR_REF), path(ID_PROPERTY)); } @@ -2144,7 +2157,11 @@ private String toWorkContributorType(String workBase) { } private String toWorkContributorRoles(String workBase) { - return join(".", workBase, dynamicArrayPath(CONTRIBUTOR_REF), path("roles")); + return join(".", workBase, dynamicArrayPath(CONTRIBUTOR_REF), path(ROLES_PROPERTY)); + } + + private String toWorkContributorIsPreferred(String workBase) { + return join(".", workBase, dynamicArrayPath(CONTRIBUTOR_REF), path(IS_PREFERRED_PROPERTY)); } private String toWorkContentTerm(String workBase) { @@ -2152,7 +2169,11 @@ private String toWorkContentTerm(String workBase) { } private String toWorkSubjectLabel(String workBase) { - return join(".", workBase, dynamicArrayPath(SUBJECT.getUri()), path("label")); + return join(".", workBase, dynamicArrayPath(SUBJECT.getUri()), path(LABEL_PROPERTY)); + } + + private String toWorkSubjectIsPreferred(String workBase) { + return join(".", workBase, dynamicArrayPath(SUBJECT.getUri()), path(IS_PREFERRED_PROPERTY)); } private String toWorkGeographicCoverageLabel(String workBase) { @@ -2160,7 +2181,11 @@ private String toWorkGeographicCoverageLabel(String workBase) { } private String toWorkGenreLabel(String workBase) { - return join(".", workBase, dynamicArrayPath(GENRE_REF), path("label")); + return join(".", workBase, dynamicArrayPath(GENRE_REF), path(LABEL_PROPERTY)); + } + + private String toWorkGenreIsPreferred(String workBase) { + return join(".", workBase, dynamicArrayPath(GENRE_REF), path(IS_PREFERRED_PROPERTY)); } private String toWorkDateStart(String workBase) { diff --git a/src/test/java/org/folio/linked/data/test/MonographTestUtil.java b/src/test/java/org/folio/linked/data/test/MonographTestUtil.java index 718fb7cc..7efe25f1 100644 --- a/src/test/java/org/folio/linked/data/test/MonographTestUtil.java +++ b/src/test/java/org/folio/linked/data/test/MonographTestUtil.java @@ -77,6 +77,7 @@ import static org.folio.ld.dictionary.PropertyDictionary.QUALIFIER; import static org.folio.ld.dictionary.PropertyDictionary.RELATED_PARTS; import static org.folio.ld.dictionary.PropertyDictionary.REPRODUCTION_NOTE; +import static org.folio.ld.dictionary.PropertyDictionary.RESOURCE_PREFERRED; import static org.folio.ld.dictionary.PropertyDictionary.SIMPLE_PLACE; import static org.folio.ld.dictionary.PropertyDictionary.SOURCE; import static org.folio.ld.dictionary.PropertyDictionary.STATEMENT_OF_RESPONSIBILITY; @@ -356,7 +357,8 @@ public static Resource getSampleWork(Resource linkedInstance) { var creatorPerson = createResource( Map.of( NAME, List.of("name-CREATOR-PERSON"), - LCNAF_ID, List.of("2002801801-PERSON") + LCNAF_ID, List.of("2002801801-PERSON"), + RESOURCE_PREFERRED, List.of("true") ), Set.of(PERSON), emptyMap() @@ -386,7 +388,8 @@ public static Resource getSampleWork(Resource linkedInstance) { var contributorPerson = createResource( Map.of( NAME, List.of("name-CONTRIBUTOR-PERSON"), - LCNAF_ID, List.of("2002801801-PERSON") + LCNAF_ID, List.of("2002801801-PERSON"), + RESOURCE_PREFERRED, List.of("true") ), Set.of(PERSON), emptyMap() @@ -425,12 +428,13 @@ public static Resource getSampleWork(Resource linkedInstance) { var subject1 = createResource( Map.of( - NAME, List.of("Subject 1") + NAME, List.of("Subject 1"), + RESOURCE_PREFERRED, List.of("true") ), Set.of(CONCEPT), emptyMap() ).setLabel("subject 1") - .setId(-2609581195837993519L); + .setId(5116157127128345626L); var subject2 = createResource( Map.of( @@ -465,7 +469,8 @@ public static Resource getSampleWork(Resource linkedInstance) { var genre1 = createResource( Map.of( - NAME, List.of("genre 1") + NAME, List.of("genre 1"), + RESOURCE_PREFERRED, List.of("true") ), Set.of(FORM), emptyMap() diff --git a/src/test/resources/samples/work_and_instance_ref.json b/src/test/resources/samples/work_and_instance_ref.json index 274fa2cd..457bf3ff 100644 --- a/src/test/resources/samples/work_and_instance_ref.json +++ b/src/test/resources/samples/work_and_instance_ref.json @@ -119,7 +119,7 @@ ], "http://bibfra.me/vocab/lite/subject": [ { - "id": "-2609581195837993519" + "id": "5116157127128345626" }, { "id": "-643516859818423084"