Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Concept label generation now orders labels as FOCUS first, followed by sorted SUB_FOCUS entries [MODLD-913](https://folio-org.atlassian.net/browse/MODLD-913)
- Update Predicate Dictionary: add IS_TRANSLATION_OF, RELATED_WORK, ADAPTED_AS_MOTION_PICTURE, SEQUEL, SEQUEL_TO and remove RELATED_TO [MODLD-1002](https://folio-org.atlassian.net/browse/MODLD-1002)
- Fix the relation URLs to match the URLs defined in https://bibfra.me/vocab/relation [MODLD-1011](https://folio-org.atlassian.net/browse/MODLD-1011)
- Create TitleLabelGenerator [MODLD-998](https://folio-org.atlassian.net/browse/MODLD-998)

## v1.9.9 (13-02-2026)
- Update Mapping for 300$b & $e (Physical description & Accompanying material) [MODLD-508](https://folio-org.atlassian.net/browse/MODLD-508)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.List;
import org.folio.ld.dictionary.label.generators.ConceptLabelGenerator;
import org.folio.ld.dictionary.label.generators.HubLabelGenerator;
import org.folio.ld.dictionary.label.generators.TitleLabelGenerator;
import org.folio.ld.dictionary.model.Resource;

public class LabelGeneratorService {
Expand All @@ -12,7 +13,8 @@ public class LabelGeneratorService {
public LabelGeneratorService() {
this.generators = List.of(
new ConceptLabelGenerator(),
new HubLabelGenerator()
new HubLabelGenerator(),
new TitleLabelGenerator()
);
}

Expand Down
17 changes: 17 additions & 0 deletions src/main/java/org/folio/ld/dictionary/label/LabelHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.folio.ld.dictionary.label;

import java.util.Optional;
import lombok.experimental.UtilityClass;
import org.folio.ld.dictionary.model.Resource;
import tools.jackson.databind.JsonNode;

@UtilityClass
public class LabelHelper {
public static Optional<String> getPropertyValue(Resource resource, String property) {
return Optional.of(resource)
.map(Resource::getDoc)
.map(doc -> doc.get(property))
.map(node -> node.get(0))
.map(JsonNode::asString);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static org.folio.ld.dictionary.PredicateDictionary.TITLE;
import static org.folio.ld.dictionary.PropertyDictionary.TERM;
import static org.folio.ld.dictionary.ResourceTypeDictionary.HUB;
import static org.folio.ld.dictionary.label.LabelHelper.getPropertyValue;

import java.util.Optional;
import java.util.stream.Stream;
Expand All @@ -15,7 +16,6 @@
import org.folio.ld.dictionary.label.LabelGenerator;
import org.folio.ld.dictionary.model.Resource;
import org.folio.ld.dictionary.model.ResourceEdge;
import tools.jackson.databind.JsonNode;

public class HubLabelGenerator implements LabelGenerator {
@Override
Expand Down Expand Up @@ -52,12 +52,4 @@ private Stream<Resource> getOutgoingEdges(Resource resource, PredicateDictionary
.filter(re -> re.getPredicate().equals(predicate))
.map(ResourceEdge::getTarget);
}

private Optional<String> getPropertyValue(Resource resource, String property) {
return Optional.of(resource)
.map(Resource::getDoc)
.map(doc -> doc.get(property))
.map(node -> node.get(0))
.map(JsonNode::asString);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.folio.ld.dictionary.label.generators;

import static java.util.stream.Collectors.joining;
import static org.folio.ld.dictionary.PropertyDictionary.MAIN_TITLE;
import static org.folio.ld.dictionary.PropertyDictionary.PART_NAME;
import static org.folio.ld.dictionary.PropertyDictionary.PART_NUMBER;
import static org.folio.ld.dictionary.PropertyDictionary.SUBTITLE;
import static org.folio.ld.dictionary.ResourceTypeDictionary.ABBREVIATED_TITLE;
import static org.folio.ld.dictionary.ResourceTypeDictionary.PARALLEL_TITLE;
import static org.folio.ld.dictionary.ResourceTypeDictionary.TITLE;
import static org.folio.ld.dictionary.ResourceTypeDictionary.VARIANT_TITLE;
import static org.folio.ld.dictionary.label.LabelHelper.getPropertyValue;

import java.util.Optional;
import java.util.stream.Stream;
import org.folio.ld.dictionary.label.LabelGenerator;
import org.folio.ld.dictionary.model.Resource;

public class TitleLabelGenerator implements LabelGenerator {
@Override
public boolean supports(Resource resource) {
return resource.isOfType(TITLE)
|| resource.isOfType(VARIANT_TITLE)
|| resource.isOfType(PARALLEL_TITLE)
|| resource.isOfType(ABBREVIATED_TITLE);
}

@Override
public String getLabel(Resource resource) {
var mainTitle = getPropertyValue(resource, MAIN_TITLE.getValue());
var subtitle = getPropertyValue(resource, SUBTITLE.getValue());
var partNumber = getPropertyValue(resource, PART_NUMBER.getValue());
var partName = getPropertyValue(resource, PART_NAME.getValue());

return Stream.of(mainTitle, subtitle, partNumber, partName)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(joining(" "));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.folio.ld.dictionary.label;

import static org.assertj.core.api.Assertions.assertThat;
import static org.folio.ld.dictionary.ResourceTypeDictionary.ABBREVIATED_TITLE;
import static org.folio.ld.dictionary.ResourceTypeDictionary.PARALLEL_TITLE;
import static org.folio.ld.dictionary.ResourceTypeDictionary.TITLE;
import static org.folio.ld.dictionary.ResourceTypeDictionary.VARIANT_TITLE;

import java.util.stream.Stream;
import lombok.SneakyThrows;
import org.folio.ld.dictionary.ResourceTypeDictionary;
import org.folio.ld.dictionary.model.Resource;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import tools.jackson.databind.json.JsonMapper;

class TitleLabelGeneratorTest {
private final JsonMapper mapper = new JsonMapper();
private final LabelGeneratorService generator = new LabelGeneratorService();

@ParameterizedTest
@MethodSource("supportedTitleTypes")
@SneakyThrows
void getLabel_joinsAvailableTitleProperties(ResourceTypeDictionary type) {
var title = new Resource()
.setId(1L)
.addType(type)
.setDoc(mapper.readTree("""
{
"http://bibfra.me/vocab/library/mainTitle": ["Main"],
"http://bibfra.me/vocab/library/subTitle": ["Subtitle"],
"http://bibfra.me/vocab/library/partNumber": ["Part 1"],
"http://bibfra.me/vocab/library/partName": ["Part Name"]
}
"""));

assertThat(generator.getLabel(title)).isEqualTo("Main Subtitle Part 1 Part Name");
}

@Test
@SneakyThrows
void getLabel_skipsMissingProperties() {
var title = new Resource()
.setId(1L)
.addType(TITLE)
.setDoc(mapper.readTree("""
{
"http://bibfra.me/vocab/library/mainTitle": ["Main"],
"http://bibfra.me/vocab/library/partName": ["Part Name"]
}
"""));

assertThat(generator.getLabel(title)).isEqualTo("Main Part Name");
}

private static Stream<ResourceTypeDictionary> supportedTitleTypes() {
return Stream.of(TITLE, VARIANT_TITLE, PARALLEL_TITLE, ABBREVIATED_TITLE);
}
}
Loading