Skip to content

Commit

Permalink
MODLD-516: Update API to support IllustrativeContent of the Work (#85)
Browse files Browse the repository at this point in the history
* MODLD-516: Update API to support IllustrativeContent of the Work

* MODLD-516: Review fixes

* MODLD-516: Change mapper package
  • Loading branch information
AndreiBordak authored Jan 6, 2025
1 parent 2b1fdbe commit 11df62d
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static org.folio.ld.dictionary.PredicateDictionary.GENRE;
import static org.folio.ld.dictionary.PredicateDictionary.GEOGRAPHIC_COVERAGE;
import static org.folio.ld.dictionary.PredicateDictionary.GOVERNMENT_PUBLICATION;
import static org.folio.ld.dictionary.PredicateDictionary.ILLUSTRATIONS;
import static org.folio.ld.dictionary.PredicateDictionary.INSTANTIATES;
import static org.folio.ld.dictionary.PredicateDictionary.LANGUAGE;
import static org.folio.ld.dictionary.PredicateDictionary.ORIGIN_PLACE;
Expand Down Expand Up @@ -88,6 +89,8 @@ public Resource toEntity(Object dto, Resource parentEntity) {
coreMapper.addOutgoingEdges(work, WorkRequest.class, workDto.getTargetAudience(), TARGET_AUDIENCE);
coreMapper.addOutgoingEdges(work, WorkRequest.class, workDto.getLanguage(), LANGUAGE);
coreMapper.addIncomingEdges(work, WorkRequest.class, workDto.getInstanceReference(), INSTANTIATES);
coreMapper.addOutgoingEdges(work, WorkRequest.class, workDto.getIllustrations(), ILLUSTRATIONS);

work.setId(hashService.hash(work));
return work;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.folio.linked.data.mapper.dto.monograph.work.sub;

import static org.folio.ld.dictionary.ResourceTypeDictionary.CATEGORY;

import org.folio.ld.dictionary.PredicateDictionary;
import org.folio.linked.data.domain.dto.Category;
import org.folio.linked.data.domain.dto.CategoryResponse;
import org.folio.linked.data.domain.dto.WorkResponse;
import org.folio.linked.data.mapper.dto.common.CoreMapper;
import org.folio.linked.data.mapper.dto.common.MapperUnit;
import org.folio.linked.data.mapper.dto.monograph.common.CategoryMapperUnit;
import org.folio.linked.data.service.resource.hash.HashService;
import org.springframework.stereotype.Component;

@Component
@MapperUnit(type = CATEGORY, predicate = PredicateDictionary.ILLUSTRATIONS, requestDto = Category.class)
public class IllustrationsMapperUnit extends CategoryMapperUnit {

private static final String LABEL = "Illustrative Content";
private static final String LINK = "http://id.loc.gov/vocabulary/millus";
private static final String LINK_PREFIX = "http://id.loc.gov/vocabulary/millus/";

public IllustrationsMapperUnit(HashService hashService, CoreMapper coreMapper) {
super(hashService, coreMapper);
}

@Override
protected void addToParent(CategoryResponse category, Object parentDto) {
if (parentDto instanceof WorkResponse work) {
work.addIllustrationsItem(category);
}
}

@Override
protected String getCategorySetLabel() {
return LABEL;
}

@Override
protected String getCategorySetLink() {
return LINK;
}

@Override
public String getLinkPrefix() {
return LINK_PREFIX;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@
"$ref": "../common/Dissertation.json"
},
"x-json-property": "http://bibfra.me/vocab/scholar/dissertation"
},
"illustrations": {
"type": "array",
"items": {
"type": "object",
"$ref": "../common/Category.json"
},
"x-json-property": "http://bibfra.me/vocab/marc/illustrations"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@
"$ref": "DissertationResponse.json"
},
"x-json-property": "http://bibfra.me/vocab/scholar/dissertation"
},
"illustrations": {
"type": "array",
"items": {
"type": "object",
"$ref": "CategoryResponse.json"
},
"x-json-property": "http://bibfra.me/vocab/marc/illustrations"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import static org.folio.ld.dictionary.PredicateDictionary.GENRE;
import static org.folio.ld.dictionary.PredicateDictionary.GEOGRAPHIC_COVERAGE;
import static org.folio.ld.dictionary.PredicateDictionary.GOVERNMENT_PUBLICATION;
import static org.folio.ld.dictionary.PredicateDictionary.ILLUSTRATIONS;
import static org.folio.ld.dictionary.PredicateDictionary.INSTANTIATES;
import static org.folio.ld.dictionary.PredicateDictionary.IS_DEFINED_BY;
import static org.folio.ld.dictionary.PredicateDictionary.LANGUAGE;
Expand Down Expand Up @@ -152,6 +153,9 @@
import static org.folio.linked.data.test.resource.ResourceJsonPath.toEditionStatement;
import static org.folio.linked.data.test.resource.ResourceJsonPath.toExtent;
import static org.folio.linked.data.test.resource.ResourceJsonPath.toId;
import static org.folio.linked.data.test.resource.ResourceJsonPath.toIllustrationsCode;
import static org.folio.linked.data.test.resource.ResourceJsonPath.toIllustrationsLink;
import static org.folio.linked.data.test.resource.ResourceJsonPath.toIllustrationsTerm;
import static org.folio.linked.data.test.resource.ResourceJsonPath.toInstance;
import static org.folio.linked.data.test.resource.ResourceJsonPath.toInstanceNotesTypes;
import static org.folio.linked.data.test.resource.ResourceJsonPath.toInstanceNotesValues;
Expand Down Expand Up @@ -614,8 +618,8 @@ void deleteResourceById_shouldDeleteRootInstanceAndRootEdges_reindexWork() throw
var work = getSampleWork(null);
var instance = resourceTestService.saveGraph(getSampleInstanceResource(null, work));
assertThat(resourceTestService.findById(instance.getId())).isPresent();
assertThat(resourceTestService.countResources()).isEqualTo(57);
assertThat(resourceTestService.countEdges()).isEqualTo(59);
assertThat(resourceTestService.countResources()).isEqualTo(58);
assertThat(resourceTestService.countEdges()).isEqualTo(60);
var requestBuilder = delete(RESOURCE_URL + "/" + instance.getId())
.contentType(APPLICATION_JSON)
.headers(defaultHeaders(env));
Expand All @@ -626,9 +630,9 @@ void deleteResourceById_shouldDeleteRootInstanceAndRootEdges_reindexWork() throw
// then
resultActions.andExpect(status().isNoContent());
assertThat(resourceTestService.existsById(instance.getId())).isFalse();
assertThat(resourceTestService.countResources()).isEqualTo(56);
assertThat(resourceTestService.countResources()).isEqualTo(57);
assertThat(resourceTestService.findEdgeById(instance.getOutgoingEdges().iterator().next().getId())).isNotPresent();
assertThat(resourceTestService.countEdges()).isEqualTo(41);
assertThat(resourceTestService.countEdges()).isEqualTo(42);
checkSearchIndexMessage(work.getId(), UPDATE);
checkIndexDate(work.getId().toString());
}
Expand All @@ -638,8 +642,8 @@ void deleteResourceById_shouldDeleteRootWorkAndRootEdges() throws Exception {
// given
var existed = resourceTestService.saveGraph(getSampleWork(getSampleInstanceResource(null, null)));
assertThat(resourceTestService.findById(existed.getId())).isPresent();
assertThat(resourceTestService.countResources()).isEqualTo(57);
assertThat(resourceTestService.countEdges()).isEqualTo(59);
assertThat(resourceTestService.countResources()).isEqualTo(58);
assertThat(resourceTestService.countEdges()).isEqualTo(60);
var requestBuilder = delete(RESOURCE_URL + "/" + existed.getId())
.contentType(APPLICATION_JSON)
.headers(defaultHeaders(env));
Expand All @@ -650,7 +654,7 @@ void deleteResourceById_shouldDeleteRootWorkAndRootEdges() throws Exception {
// then
resultActions.andExpect(status().isNoContent());
assertThat(resourceTestService.existsById(existed.getId())).isFalse();
assertThat(resourceTestService.countResources()).isEqualTo(56);
assertThat(resourceTestService.countResources()).isEqualTo(57);
assertThat(resourceTestService.findEdgeById(existed.getOutgoingEdges().iterator().next().getId())).isNotPresent();
assertThat(resourceTestService.countEdges()).isEqualTo(30);
checkSearchIndexMessage(existed.getId(), DELETE);
Expand Down Expand Up @@ -863,7 +867,10 @@ private void validateWorkResponse(ResultActions resultActions, String workBase)
.andExpect(jsonPath(toWorkGovPublicationLink(workBase), equalTo("http://id.loc.gov/vocabulary/mgovtpubtype/a")))
.andExpect(jsonPath(toWorkTargetAudienceCode(workBase), equalTo("b")))
.andExpect(jsonPath(toWorkTargetAudienceTerm(workBase), equalTo("Primary")))
.andExpect(jsonPath(toWorkTargetAudienceLink(workBase), equalTo("http://id.loc.gov/vocabulary/maudience/pri")));
.andExpect(jsonPath(toWorkTargetAudienceLink(workBase), equalTo("http://id.loc.gov/vocabulary/maudience/pri")))
.andExpect(jsonPath(toIllustrationsCode(workBase), equalTo("code")))
.andExpect(jsonPath(toIllustrationsLink(workBase), equalTo("http://id.loc.gov/vocabulary/millus/code")))
.andExpect(jsonPath(toIllustrationsTerm(workBase), equalTo("illustrations term")));
if (workBase.equals(toWork())) {
resultActions.andExpect(jsonPath(toInstanceReference(workBase), notNullValue()));
validateInstanceResponse(resultActions, toInstanceReference(workBase));
Expand Down Expand Up @@ -1188,6 +1195,27 @@ private void validateAccessLocation(ResourceEdge edge, Resource source) {
assertThat(locator.getOutgoingEdges()).isEmpty();
}

private void validateCategory(ResourceEdge edge,
Resource source,
PredicateDictionary pred,
String label,
Map<String, String> doc,
String categorySetLabel) {
assertThat(edge.getId()).isNotNull();
assertThat(edge.getSource()).isEqualTo(source);
assertThat(edge.getPredicate().getUri()).isEqualTo(pred.getUri());
var category = edge.getTarget();
assertThat(category.getLabel()).isEqualTo(label);
assertThat(category.getTypes().iterator().next().getUri()).isEqualTo(CATEGORY.getUri());
assertThat(category.getId()).isEqualTo(hashService.hash(category));
doc.forEach((key, value) -> validateLiteral(category, key, value));
if (category.getOutgoingEdges().isEmpty()) {
return;
}
assertCategorySetIsDefinedBy(category);
assertEquals(category.getOutgoingEdges().iterator().next().getTarget().getLabel(), categorySetLabel);
}

private void validateCategory(ResourceEdge edge, Resource source, PredicateDictionary pred,
String expectedLink, String expectedCode) {
var prefix = pred.getUri().substring(pred.getUri().lastIndexOf("/") + 1);
Expand All @@ -1206,6 +1234,10 @@ private void validateCategory(ResourceEdge edge, Resource source, PredicateDicti
if (category.getOutgoingEdges().isEmpty()) {
return;
}
assertCategorySetIsDefinedBy(category);
}

private void assertCategorySetIsDefinedBy(Resource category) {
assertThat(category.getOutgoingEdges())
.extracting(ResourceEdge::getPredicate)
.extracting(PredicateEntity::getUri)
Expand Down Expand Up @@ -1233,6 +1265,10 @@ private void validateWork(Resource work, boolean validateFullInstance) {
validateParallelTitle(outgoingEdgeIterator.next(), work);
validateWorkContentType(outgoingEdgeIterator.next(), work);
validateWorkTargetAudience(outgoingEdgeIterator.next(), work);
validateCategory(outgoingEdgeIterator.next(), work, ILLUSTRATIONS, "illustrations term",
Map.of(LINK.getValue(), "http://id.loc.gov/vocabulary/millus/code", CODE.getValue(), "code"),
"Illustrative Content"
);
validateWorkGovernmentPublication(outgoingEdgeIterator.next(), work);
validateLanguage(outgoingEdgeIterator.next(), work);
validateDissertation(outgoingEdgeIterator.next(), work);
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/org/folio/linked/data/test/MonographTestUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static org.folio.ld.dictionary.PredicateDictionary.GENRE;
import static org.folio.ld.dictionary.PredicateDictionary.GOVERNMENT_PUBLICATION;
import static org.folio.ld.dictionary.PredicateDictionary.GRANTING_INSTITUTION;
import static org.folio.ld.dictionary.PredicateDictionary.ILLUSTRATIONS;
import static org.folio.ld.dictionary.PredicateDictionary.INSTANTIATES;
import static org.folio.ld.dictionary.PredicateDictionary.IS_DEFINED_BY;
import static org.folio.ld.dictionary.PredicateDictionary.LANGUAGE;
Expand Down Expand Up @@ -517,6 +518,16 @@ public static Resource getSampleWork(Resource linkedInstance) {
emptyMap()
).setLabel("eng");

var illustrations = createResource(
Map.of(
CODE, List.of("code"),
TERM, List.of("illustrations term"),
LINK, List.of("http://id.loc.gov/vocabulary/millus/code")
),
Set.of(CATEGORY),
emptyMap()
).setLabel("illustrations term");

var pred2OutgoingResources = new LinkedHashMap<PredicateDictionary, List<Resource>>();
pred2OutgoingResources.put(TITLE, List.of(primaryTitle, createParallelTitle(), createVariantTitle()));
pred2OutgoingResources.put(CLASSIFICATION, List.of(createLcClassification(), createDeweyClassification()));
Expand All @@ -535,6 +546,7 @@ public static Resource getSampleWork(Resource linkedInstance) {
pred2OutgoingResources.put(DISSERTATION, List.of(createDissertation()));
pred2OutgoingResources.put(TARGET_AUDIENCE, List.of(createTargetAudience()));
pred2OutgoingResources.put(LANGUAGE, List.of(language));
pred2OutgoingResources.put(ILLUSTRATIONS, List.of(illustrations));

var work = createResource(
Map.ofEntries(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static org.folio.ld.dictionary.PredicateDictionary.COPYRIGHT;
import static org.folio.ld.dictionary.PredicateDictionary.DISSERTATION;
import static org.folio.ld.dictionary.PredicateDictionary.GOVERNMENT_PUBLICATION;
import static org.folio.ld.dictionary.PredicateDictionary.ILLUSTRATIONS;
import static org.folio.ld.dictionary.PredicateDictionary.LANGUAGE;
import static org.folio.ld.dictionary.PredicateDictionary.MAP;
import static org.folio.ld.dictionary.PredicateDictionary.MEDIA;
Expand Down Expand Up @@ -351,6 +352,18 @@ public static String toCarrierTerm(String instanceBase) {
return join(".", instanceBase, arrayPath(CARRIER.getUri()), arrayPath(TERM.getValue()));
}

public static String toIllustrationsCode(String workBase) {
return join(".", workBase, arrayPath(ILLUSTRATIONS.getUri()), arrayPath(CODE.getValue()));
}

public static String toIllustrationsLink(String workBase) {
return join(".", workBase, arrayPath(ILLUSTRATIONS.getUri()), arrayPath(LINK.getValue()));
}

public static String toIllustrationsTerm(String workBase) {
return join(".", workBase, arrayPath(ILLUSTRATIONS.getUri()), arrayPath(TERM.getValue()));
}

public static String toCopyrightDate() {
return join(".", toInstance(), arrayPath(COPYRIGHT.getUri()), arrayPath(DATE.getValue()));
}
Expand Down
13 changes: 13 additions & 0 deletions src/test/resources/samples/work_and_instance_ref.json
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,19 @@
]
}
],
"http://bibfra.me/vocab/marc/illustrations": [
{
"http://bibfra.me/vocab/lite/link": [
"http://id.loc.gov/vocabulary/millus/code"
],
"http://bibfra.me/vocab/marc/term": [
"illustrations term"
],
"http://bibfra.me/vocab/marc/code": [
"code"
]
}
],
"http://bibfra.me/vocab/scholar/dissertation": [
{
"http://bibfra.me/vocab/lite/label": [
Expand Down

0 comments on commit 11df62d

Please sign in to comment.