Skip to content

Commit

Permalink
Merge pull request #2655 from dbmdz/hierarchically-filled
Browse files Browse the repository at this point in the history
Expand the `DigitalObject` with its `Item`, `Manifestation` & `Work`
  • Loading branch information
daforster authored Nov 2, 2023
2 parents b5bdb3c + 0b238ab commit c551b96
Show file tree
Hide file tree
Showing 14 changed files with 202 additions and 80 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

### Added

- Hierarchically filled `DigitalObject` (by UUID or identifier); the `lastModified` date of the `DigitalObject`
is set to the newest of its WMI objects, the WMI objects lose their date therefor
- Identifiers of objects enclosed in `Work`, `Manifestation` & `Item`
- SQL function to retrieve an identifiable's identifiers
- SQL function to convert `dbidentifier[]` (composite database type) into json(b)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import de.digitalcollections.model.list.paging.PageRequest;
import de.digitalcollections.model.list.paging.PageResponse;
import java.net.http.HttpClient;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -43,8 +45,20 @@ public PageResponse<T> find(PageRequest pageRequest) throws TechnicalException {
}

public T getByUuid(UUID uuid) throws TechnicalException {
return getByUuid(uuid, null);
}

public T getByUuid(UUID uuid, Map<String, String> additionalParameters)
throws TechnicalException {
try {
return doGetRequestForObject(String.format("%s/%s", baseEndpoint, uuid));
String params = "";
if (additionalParameters != null && !additionalParameters.isEmpty()) {
params =
additionalParameters.entrySet().stream()
.map(entry -> String.format("%s=%s", entry.getKey(), entry.getValue()))
.collect(Collectors.joining("&", "?", ""));
}
return doGetRequestForObject(String.format("%s/%s%s", baseEndpoint, uuid, params));
} catch (ResourceNotFoundException e) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ public DigitalObject getByIdentifierAndFillWEMI(String namespace, String id)
return getByIdentifier(namespace, id, Map.of("fill-wemi", "true"));
}

public DigitalObject getByUuidAndFillWEMI(UUID uuid) throws TechnicalException {
return getByUuid(uuid, Map.of("fill-wemi", "true"));
}

public List<FileResource> getFileResources(UUID uuid) throws TechnicalException {
return doGetRequestForObjectList(
String.format("%s/%s/fileresources", baseEndpoint, uuid), FileResource.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.DigitalObjectRepositoryImpl;
import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.EntityRepositoryImpl;
import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.agent.AgentRepositoryImpl;
import de.digitalcollections.model.identifiable.Identifier;
import de.digitalcollections.model.identifiable.entity.agent.Agent;
import de.digitalcollections.model.identifiable.entity.agent.CorporateBody;
import de.digitalcollections.model.identifiable.entity.agent.Family;
Expand All @@ -24,8 +25,10 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.jdbi.v3.core.Jdbi;
import org.jdbi.v3.core.generic.GenericType;
import org.jdbi.v3.core.result.RowView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -82,6 +85,8 @@ protected void fullReduceRowsBiConsumer(Map<UUID, Item> map, RowView rowView) {
if (item.getPartOfItem().getLabel() != null) return;
LocalizedText partOfItemLabel = rowView.getColumn("poi_label", LocalizedText.class);
item.getPartOfItem().setLabel(partOfItemLabel);
Set<Identifier> ids = rowView.getColumn("poi_identifiers", new SetOfIdentifiers());
if (ids != null) item.getPartOfItem().setIdentifiers(ids);
}

// same for manifestation
Expand All @@ -90,6 +95,9 @@ protected void fullReduceRowsBiConsumer(Map<UUID, Item> map, RowView rowView) {
LocalizedText manifestationLabel =
rowView.getColumn(MAPPING_PREFIX + "_manifestation_label", LocalizedText.class);
item.getManifestation().setLabel(manifestationLabel);
Set<Identifier> ids =
rowView.getColumn(MAPPING_PREFIX + "_manifestation_identifiers", new SetOfIdentifiers());
if (ids != null) item.getManifestation().setIdentifiers(ids);
}
}

Expand Down Expand Up @@ -281,8 +289,8 @@ public String getSqlSelectAllFields(String tableAlias, String mappingPrefix) {
return getSqlSelectReducedFields(tableAlias, mappingPrefix)
+ """
, %1$s.exemplifies_manifestation %2$s_exemplifies_manifestation,
poi.label poi_label,
%3$s.label %2$s_manifestation_label
poi.label poi_label, get_identifiers(poi.uuid) poi_identifiers,
%3$s.label %2$s_manifestation_label, get_identifiers(%3$s.uuid) %2$s_manifestation_identifiers
"""
.formatted(tableAlias, mappingPrefix, ManifestationRepositoryImpl.TABLE_ALIAS);
}
Expand Down Expand Up @@ -314,7 +322,10 @@ public String getSqlSelectReducedFields(String tableAlias, String mappingPrefix)
+ mappingPrefix
+ "_manifestation_uuid, "
+ agentRepository.getSqlSelectReducedFields(
"holdertable", AgentRepositoryImpl.MAPPING_PREFIX);
"holdertable", AgentRepositoryImpl.MAPPING_PREFIX)
+ ", get_identifiers(holdertable.uuid) "
+ AgentRepositoryImpl.MAPPING_PREFIX
+ "_identifiers";
}

@Override
Expand Down Expand Up @@ -345,4 +356,6 @@ public void update(Item item) throws RepositoryException {
bindings.put("holder_uuids", extractUuids(item.getHolders()));
super.update(item, bindings);
}

private static class SetOfIdentifiers extends GenericType<Set<Identifier>> {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import de.digitalcollections.cudami.server.backend.impl.jdbi.type.TitleMapper;
import de.digitalcollections.model.RelationSpecification;
import de.digitalcollections.model.identifiable.IdentifiableObjectType;
import de.digitalcollections.model.identifiable.Identifier;
import de.digitalcollections.model.identifiable.entity.Entity;
import de.digitalcollections.model.identifiable.entity.agent.Agent;
import de.digitalcollections.model.identifiable.entity.agent.CorporateBody;
Expand Down Expand Up @@ -46,6 +47,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.Vector;
import java.util.stream.Stream;
Expand Down Expand Up @@ -214,6 +216,8 @@ protected void basicReduceRowsBiConsumer(Map<UUID, Manifestation> map, RowView r
.identifiableObjectType(
rowView.getColumn(
"parent_identifiableObjectType", IdentifiableObjectType.class))
.identifiers(
rowView.getColumn("parent_identifiers", new GenericType<Set<Identifier>>() {}))
.build();
manifestation
.getParents()
Expand Down Expand Up @@ -441,10 +445,19 @@ public String getSqlSelectAllFields(String tableAlias, String mappingPrefix) {
"""
.formatted(tableAlias, mappingPrefix)
// publishers
+ "%s, %s"
.formatted(
agentRepository.getSqlSelectReducedFields(),
humanSettlementRepository.getSqlSelectReducedFields());
+ """
{{agentFields}},
{{humanSettlementFields}},
get_identifiers({{agentAlias}}.uuid) {{agentMap}}_identifiers,
get_identifiers({{humanSettleAlias}}.uuid) {{humanSettleMap}}_identifiers
"""
.replace("{{agentFields}}", agentRepository.getSqlSelectReducedFields())
.replace(
"{{humanSettlementFields}}", humanSettlementRepository.getSqlSelectReducedFields())
.replace("{{agentAlias}}", agentRepository.getTableAlias())
.replace("{{agentMap}}", agentRepository.getMappingPrefix())
.replace("{{humanSettleAlias}}", humanSettlementRepository.getTableAlias())
.replace("{{humanSettleMap}}", humanSettlementRepository.getMappingPrefix());
}

@Override
Expand All @@ -471,7 +484,7 @@ public String getSqlSelectReducedFields(String tableAlias, String mappingPrefix)
, %1$s.expressiontypes %2$s_expressionTypes, %1$s.language %2$s_language, %1$s.manifestationtype %2$s_manifestationType,
%1$s.manufacturingtype %2$s_manufacturingType, %1$s.mediatypes %2$s_mediaTypes,
%1$s.titles %2$s_titles,
%3$s.uuid %4$s_uuid, %3$s.label %4$s_label,
%3$s.uuid %4$s_uuid, get_identifiers(%3$s.uuid) %4$s_identifiers, %3$s.label %4$s_label,
"""
.formatted(
tableAlias,
Expand All @@ -483,17 +496,20 @@ public String getSqlSelectReducedFields(String tableAlias, String mappingPrefix)
mms.title parent_title, mms.sortKey parent_sortKey,
parent.uuid parent_uuid, parent.label parent_label, parent.titles parent_titles, parent.manifestationtype parent_manifestationType,
parent.refid parent_refId, parent.notes parent_notes, parent.created parent_created, parent.last_modified parent_lastModified,
parent.identifiable_objecttype parent_identifiableObjectType,
parent.identifiable_objecttype parent_identifiableObjectType, get_identifiers(parent.uuid) parent_identifiers,
"""
// relations
+ """
%1$s.predicate %2$s_predicate, %1$s.sortindex %2$s_sortindex,
%1$s.additional_predicates %2$s_additionalPredicates,
max(%1$s.sortindex) OVER (PARTITION BY %3$s.uuid) relation_max_sortindex, """
.formatted(
EntityToEntityRelationRepositoryImpl.TABLE_ALIAS,
EntityToEntityRelationRepositoryImpl.MAPPING_PREFIX,
tableAlias)
{{entityRelationAlias}}.predicate {{entityRelationMap}}_predicate, {{entityRelationAlias}}.sortindex {{entityRelationMap}}_sortindex,
{{entityRelationAlias}}.additional_predicates {{entityRelationMap}}_additionalPredicates,
max({{entityRelationAlias}}.sortindex) OVER (PARTITION BY {{tableAlias}}.uuid) relation_max_sortindex,
get_identifiers({{entityAlias}}.uuid) {{entityMapping}}_identifiers,
"""
.replace("{{tableAlias}}", tableAlias)
.replace("{{entityRelationAlias}}", EntityToEntityRelationRepositoryImpl.TABLE_ALIAS)
.replace("{{entityRelationMap}}", EntityToEntityRelationRepositoryImpl.MAPPING_PREFIX)
.replace("{{entityAlias}}", entityRepository.getTableAlias())
.replace("{{entityMapping}}", entityRepository.getMappingPrefix())
+ entityRepository.getSqlSelectReducedFields();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import de.digitalcollections.cudami.server.backend.impl.jdbi.type.LocalDateRangeMapper;
import de.digitalcollections.cudami.server.backend.impl.jdbi.type.TitleMapper;
import de.digitalcollections.model.identifiable.IdentifiableObjectType;
import de.digitalcollections.model.identifiable.Identifier;
import de.digitalcollections.model.identifiable.entity.Entity;
import de.digitalcollections.model.identifiable.entity.agent.Agent;
import de.digitalcollections.model.identifiable.entity.relation.EntityRelation;
Expand Down Expand Up @@ -126,6 +127,8 @@ protected void basicReduceRowsBiConsumer(Map<UUID, Work> map, RowView rowView) {
.identifiableObjectType(
rowView.getColumn(
"parent_identifiableObjectType", IdentifiableObjectType.class))
.identifiers(
rowView.getColumn("parent_identifiers", new GenericType<Set<Identifier>>() {}))
.build();
work.getParents().add(parent);
}
Expand Down Expand Up @@ -346,18 +349,20 @@ public String getSqlSelectReducedFields(String tableAlias, String mappingPrefix)
+ """
parent.uuid parent_uuid, parent.label parent_label, parent.titles parent_titles,
parent.refid parent_refId, parent.notes parent_notes, parent.created parent_created, parent.last_modified parent_lastModified,
parent.identifiable_objecttype parent_identifiableObjectType,
parent.identifiable_objecttype parent_identifiableObjectType, get_identifiers(parent.uuid) parent_identifiers,
"""
// relations
+ """
%1$s.predicate %2$s_predicate, %1$s.sortindex %2$s_sortindex,
%1$s.additional_predicates %2$s_additionalPredicates,
max(%1$s.sortindex) OVER (PARTITION BY %3$s.uuid) relation_max_sortindex,
"""
.formatted(
EntityToEntityRelationRepositoryImpl.TABLE_ALIAS,
EntityToEntityRelationRepositoryImpl.MAPPING_PREFIX,
tableAlias)
{{entityRelationAlias}}.predicate {{entityRelationMap}}_predicate, {{entityRelationAlias}}.sortindex {{entityRelationMap}}_sortindex,
{{entityRelationAlias}}.additional_predicates {{entityRelationMap}}_additionalPredicates,
max({{entityRelationAlias}}.sortindex) OVER (PARTITION BY {{tableAlias}}.uuid) relation_max_sortindex,
get_identifiers({{entityAlias}}.uuid) {{entityMapping}}_identifiers,
"""
.replace("{{tableAlias}}", tableAlias)
.replace("{{entityRelationAlias}}", EntityToEntityRelationRepositoryImpl.TABLE_ALIAS)
.replace("{{entityRelationMap}}", EntityToEntityRelationRepositoryImpl.MAPPING_PREFIX)
.replace("{{entityAlias}}", entityRepository.getTableAlias())
.replace("{{entityMapping}}", entityRepository.getMappingPrefix())
+ entityRepository.getSqlSelectReducedFields();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ void setup(
@Test
@DisplayName("can save an item")
public void saveItem() throws RepositoryException {
Item item = Item.builder().label(Locale.GERMAN, "Item").build();
Item item =
Item.builder()
.label(Locale.GERMAN, "Item")
.identifier(Identifier.builder().namespace("namespace").id("id").build())
.build();
saveAndAssertTimestampsAndEqualityToSaveable(item);
}

Expand Down Expand Up @@ -165,11 +169,13 @@ void saveAndRetrieveTwoHolders() throws RepositoryException {
CorporateBody.builder()
.label(Locale.GERMAN, "A Company")
.identifiableObjectType(IdentifiableObjectType.CORPORATE_BODY)
.identifier(Identifier.builder().namespace("namespace").id("company").build())
.build());
holders.add(
CorporateBody.builder()
.label(Locale.GERMAN, "Some Amazing Company")
.identifiableObjectType(IdentifiableObjectType.CORPORATE_BODY)
.identifier(Identifier.builder().namespace("namespace").id("companü").build())
.build());

CorporateBody holder0 = (CorporateBody) holders.get(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,22 @@
import de.digitalcollections.model.identifiable.entity.agent.CorporateBody;
import de.digitalcollections.model.identifiable.entity.agent.Person;
import de.digitalcollections.model.identifiable.entity.geo.location.HumanSettlement;
import de.digitalcollections.model.identifiable.entity.manifestation.*;
import de.digitalcollections.model.identifiable.entity.manifestation.ExpressionType;
import de.digitalcollections.model.identifiable.entity.manifestation.Manifestation;
import de.digitalcollections.model.identifiable.entity.manifestation.ProductionInfo;
import de.digitalcollections.model.identifiable.entity.manifestation.PublicationInfo;
import de.digitalcollections.model.identifiable.entity.manifestation.Publisher;
import de.digitalcollections.model.identifiable.entity.relation.EntityRelation;
import de.digitalcollections.model.identifiable.entity.work.Work;
import de.digitalcollections.model.identifiable.semantic.Subject;
import de.digitalcollections.model.list.paging.PageRequest;
import de.digitalcollections.model.list.paging.PageResponse;
import de.digitalcollections.model.relation.Predicate;
import de.digitalcollections.model.text.*;
import de.digitalcollections.model.text.LocalizedStructuredContent;
import de.digitalcollections.model.text.LocalizedText;
import de.digitalcollections.model.text.StructuredContent;
import de.digitalcollections.model.text.Title;
import de.digitalcollections.model.text.TitleType;
import de.digitalcollections.model.text.contentblock.Text;
import de.digitalcollections.model.time.LocalDateRange;
import java.time.LocalDate;
Expand All @@ -40,7 +48,11 @@
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
Expand Down Expand Up @@ -86,10 +98,19 @@ void beforeEach() {
@DisplayName("1.0. Save a manifestation with parent")
void testSaveManifestation() throws RepositoryException {
// agents for relations
CorporateBody editor = CorporateBody.builder().label("Editor").addName("Editor").build();
CorporateBody editor =
CorporateBody.builder()
.label("Editor")
.addName("Editor")
.identifier(Identifier.builder().namespace("namespace").id("editor").build())
.build();
corporateBodyRepository.save(editor);
CorporateBody someoneElse =
CorporateBody.builder().label("Someone else").addName("Someone else").build();
CorporateBody.builder()
.label("Someone else")
.addName("Someone else")
.identifier(Identifier.builder().namespace("namespace").id("someoneElse").build())
.build();
corporateBodyRepository.save(someoneElse);

// predicates
Expand Down Expand Up @@ -411,6 +432,7 @@ private Manifestation prepareManifestation(
CorporateBody.builder()
.name(new LocalizedText(Locale.ENGLISH, "Publisher"))
.label(new LocalizedText(Locale.ENGLISH, "Publisher label"))
.identifier(Identifier.builder().namespace("publisherAgent").id("publisher").build())
.build();
corporateBodyRepository.save(publisherAgent);
Person productionAgent =
Expand All @@ -423,6 +445,7 @@ private Manifestation prepareManifestation(
HumanSettlement.builder()
.name(new LocalizedText(Locale.forLanguageTag("und-Latn"), "München"))
.label(Locale.forLanguageTag("und-Latn"), "München")
.identifier(Identifier.builder().namespace("publicationPlace").id("Munich").build())
.build();
humanSettlementRepository.save(publicationPlace1);
assertThat(publicationPlace1.getRefId()).isGreaterThan(0);
Expand All @@ -437,6 +460,7 @@ private Manifestation prepareManifestation(
Manifestation manifestation =
Manifestation.builder()
.label(Locale.GERMAN, "ein Label")
.identifier(Identifier.builder().namespace("manifestation-id").id("test").build())
.composition("composition")
.expressionType(ExpressionType.builder().mainType("BOOK").subType("PRINT").build())
.language(Locale.GERMAN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,11 @@ public void saveFillsAndReturnsUuid() throws RepositoryException {
@DisplayName("persists all fields of a saved work")
@Test
public void persistAllFieldsOnSave() throws RepositoryException {
Work parentWork = Work.builder().label(Locale.GERMAN, "Parent").build();
Work parentWork =
Work.builder()
.label(Locale.GERMAN, "Parent")
.identifier(Identifier.builder().namespace("parent").id("work").build())
.build();
repo.save(parentWork);

Work work =
Expand Down
Loading

0 comments on commit c551b96

Please sign in to comment.