diff --git a/dc-cudami-client/src/main/java/de/digitalcollections/cudami/client/relation/CudamiPredicatesClient.java b/dc-cudami-client/src/main/java/de/digitalcollections/cudami/client/relation/CudamiPredicatesClient.java index 822c1e997c..9facd31ca1 100644 --- a/dc-cudami-client/src/main/java/de/digitalcollections/cudami/client/relation/CudamiPredicatesClient.java +++ b/dc-cudami-client/src/main/java/de/digitalcollections/cudami/client/relation/CudamiPredicatesClient.java @@ -1,9 +1,7 @@ package de.digitalcollections.cudami.client.relation; -import static de.digitalcollections.cudami.client.CudamiRestClient.API_VERSION_PREFIX; - import com.fasterxml.jackson.databind.ObjectMapper; -import de.digitalcollections.client.BaseRestClient; +import de.digitalcollections.cudami.client.CudamiRestClient; import de.digitalcollections.model.exception.TechnicalException; import de.digitalcollections.model.relation.Predicate; import java.net.URLEncoder; @@ -11,7 +9,7 @@ import java.nio.charset.StandardCharsets; import java.util.List; -public class CudamiPredicatesClient extends BaseRestClient { +public class CudamiPredicatesClient extends CudamiRestClient { public CudamiPredicatesClient(HttpClient http, String serverUrl, ObjectMapper mapper) { super(http, serverUrl, Predicate.class, mapper, API_VERSION_PREFIX + "/predicates"); @@ -21,10 +19,21 @@ public List getAll() throws TechnicalException { return doGetRequestForObjectList(baseEndpoint, Predicate.class); } - public Predicate save(Predicate predicate) throws TechnicalException { - return doPutRequestForObject( - String.format( - "%s/%s", baseEndpoint, URLEncoder.encode(predicate.getValue(), StandardCharsets.UTF_8)), - predicate); + public Predicate update(Predicate predicate) throws TechnicalException { + if (predicate.getUuid() == null) { + // Old consumers don't set the UUID, we must provide the value in the request path + return doPutRequestForObject( + String.format( + "%s/%s", + baseEndpoint, URLEncoder.encode(predicate.getValue(), StandardCharsets.UTF_8)), + predicate); + } + + return super.update(predicate.getUuid(), predicate); + } + + public Predicate getByValue(String value) throws TechnicalException { + return doGetRequestForObject( + String.format("%s/%s", baseEndpoint, URLEncoder.encode(value, StandardCharsets.UTF_8))); } } diff --git a/dc-cudami-client/src/test/java/de/digitalcollections/cudami/client/relation/CudamiPredicatesClientTest.java b/dc-cudami-client/src/test/java/de/digitalcollections/cudami/client/relation/CudamiPredicatesClientTest.java new file mode 100644 index 0000000000..f13fa62405 --- /dev/null +++ b/dc-cudami-client/src/test/java/de/digitalcollections/cudami/client/relation/CudamiPredicatesClientTest.java @@ -0,0 +1,38 @@ +package de.digitalcollections.cudami.client.relation; + +import de.digitalcollections.cudami.client.BaseCudamiRestClientTest; +import de.digitalcollections.model.relation.Predicate; +import java.util.UUID; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +@DisplayName("The PredicatesClient") +class CudamiPredicatesClientTest + extends BaseCudamiRestClientTest { + + @Test + @DisplayName("can update without uuid (old behaviour)") + public void testUpdateWithoutUuid() throws Exception { + Predicate predicate = Predicate.builder().value("foo").build(); + client.update(predicate); + + verifyHttpRequestByMethodRelativeUrlAndRequestBody("put", "/foo", predicate); + } + + @Test + @DisplayName("can update with uuid") + public void testUpdateWithUuid() throws Exception { + UUID uuid = UUID.randomUUID(); + Predicate predicate = Predicate.builder().value("foo").uuid(uuid).build(); + client.update(uuid, predicate); + + verifyHttpRequestByMethodRelativeUrlAndRequestBody("put", "/" + uuid, predicate); + } + + @Test + @DisplayName("can find all") + public void testFindAll() throws Exception { + client.getAll(); + verifyHttpRequestByMethodAndRelativeURL("get", ""); + } +} diff --git a/dc-cudami-model/pom.xml b/dc-cudami-model/pom.xml index 2029683a4b..31a8c0bedd 100644 --- a/dc-cudami-model/pom.xml +++ b/dc-cudami-model/pom.xml @@ -13,6 +13,12 @@ dc-cudami-model jar + + 11 + ${java.version} + ${java.version} + + com.github.spotbugs diff --git a/dc-cudami-server/dc-cudami-server-backend-api/src/main/java/de/digitalcollections/cudami/server/backend/api/repository/identifiable/entity/relation/EntityRelationRepository.java b/dc-cudami-server/dc-cudami-server-backend-api/src/main/java/de/digitalcollections/cudami/server/backend/api/repository/identifiable/entity/relation/EntityRelationRepository.java index dc9749ee61..0f05d20ad3 100644 --- a/dc-cudami-server/dc-cudami-server-backend-api/src/main/java/de/digitalcollections/cudami/server/backend/api/repository/identifiable/entity/relation/EntityRelationRepository.java +++ b/dc-cudami-server/dc-cudami-server-backend-api/src/main/java/de/digitalcollections/cudami/server/backend/api/repository/identifiable/entity/relation/EntityRelationRepository.java @@ -1,5 +1,6 @@ package de.digitalcollections.cudami.server.backend.api.repository.identifiable.entity.relation; +import de.digitalcollections.cudami.server.backend.api.repository.exceptions.RepositoryException; import de.digitalcollections.model.identifiable.entity.Entity; import de.digitalcollections.model.identifiable.entity.relation.EntityRelation; import de.digitalcollections.model.list.paging.PageRequest; @@ -16,6 +17,12 @@ default void addRelation(EntityRelation relation) { void addRelation(UUID subjectEntityUuid, String predicate, UUID objectEntityUuid); + default void deleteByObject(Entity objectEntity) { + deleteByObject(objectEntity.getUuid()); + } + + void deleteByObject(UUID objectEntityUuid); + default void deleteBySubject(Entity subjectEntity) { deleteBySubject(subjectEntity.getUuid()); } @@ -47,6 +54,7 @@ default void save(EntityRelation relation) { * * @param entityRelations list of entity-predicate-entity relations to be persisted * @return list of persisted EntityRelations + * @throws RepositoryException in case of an error, e.g. a referenced predicate does not yet exist */ - List save(List entityRelations); + List save(List entityRelations) throws RepositoryException; } diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/PublisherRepositoryImpl.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/PublisherRepositoryImpl.java index facf0e35d4..6ce5e69aac 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/PublisherRepositoryImpl.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/PublisherRepositoryImpl.java @@ -81,29 +81,29 @@ public PageResponse find(PageRequest pageRequest) throws RepositoryEx // order of // array items + " LEFT JOIN " - + corporateBodyRepository.tableName + + corporateBodyRepository.getTableName() + " " - + corporateBodyRepository.tableAlias + + corporateBodyRepository.getTableAlias() + " ON " - + corporateBodyRepository.tableAlias + + corporateBodyRepository.getTableAlias() + ".uuid=" + tableAlias + ".agent_uuid" + " LEFT JOIN " - + personRepository.tableName + + personRepository.getTableName() + " " - + personRepository.tableAlias + + personRepository.getTableAlias() + " ON " - + personRepository.tableAlias + + personRepository.getTableAlias() + ".uuid=" + tableAlias + ".agent_uuid" + " LEFT JOIN " - + humanSettlementRepository.tableName + + humanSettlementRepository.getTableName() + " " - + humanSettlementRepository.tableAlias + + humanSettlementRepository.getTableAlias() + " ON " - + humanSettlementRepository.tableAlias + + humanSettlementRepository.getTableAlias() + ".uuid=l.id"); Map argumentMappings = new HashMap<>(); @@ -150,29 +150,29 @@ public Publisher getByUuid(UUID uuid) throws RepositoryException { + " " + tableAlias + " LEFT JOIN " - + corporateBodyRepository.tableName + + corporateBodyRepository.getTableName() + " " - + corporateBodyRepository.tableAlias + + corporateBodyRepository.getTableAlias() + " ON " - + corporateBodyRepository.tableAlias + + corporateBodyRepository.getTableAlias() + ".uuid=" + tableAlias + ".agent_uuid" + " LEFT JOIN " - + personRepository.tableName + + personRepository.getTableName() + " " - + personRepository.tableAlias + + personRepository.getTableAlias() + " ON " - + personRepository.tableAlias + + personRepository.getTableAlias() + ".uuid=" + tableAlias + ".agent_uuid" + " LEFT JOIN " - + humanSettlementRepository.tableName + + humanSettlementRepository.getTableName() + " " - + humanSettlementRepository.tableAlias + + humanSettlementRepository.getTableAlias() + " ON " - + humanSettlementRepository.tableAlias + + humanSettlementRepository.getTableAlias() + ".uuid=" + " ANY(" + tableAlias @@ -208,18 +208,19 @@ public Publisher getByUuid(UUID uuid) throws RepositoryException { }); UUID corporateBodyUuid = - rowView.getColumn(corporateBodyRepository.mappingPrefix + "_uuid", UUID.class); + rowView.getColumn(corporateBodyRepository.getMappingPrefix() + "_uuid", UUID.class); if (corporateBodyUuid != null) { publisher.setAgent(rowView.getRow(CorporateBody.class)); } - UUID personUuid = rowView.getColumn(personRepository.mappingPrefix + "_uuid", UUID.class); + UUID personUuid = + rowView.getColumn(personRepository.getMappingPrefix() + "_uuid", UUID.class); if (personUuid != null) { publisher.setAgent(rowView.getRow(Person.class)); } UUID locationUuid = - rowView.getColumn(humanSettlementRepository.mappingPrefix + "_uuid", UUID.class); + rowView.getColumn(humanSettlementRepository.getMappingPrefix() + "_uuid", UUID.class); if (locationUuid != null) { publisher.addLocation(rowView.getRow(HumanSettlement.class)); } @@ -338,11 +339,9 @@ public String getColumnName(String modelProperty) { case "uuid": return tableAlias + ".uuid"; case "agent_uuid": - return tableAlias + ".agent_uuid::varchar"; - case "location_uuid": - return tableAlias + ".location_uuids::varchar"; + return tableAlias + ".agent_uuid::UUID"; case "location_uuids": - return tableAlias + ".location_uuids::varchar[]"; + return tableAlias + ".location_uuids::UUID[]"; case "publisherPresentation": return tableAlias + ".publisherPresentation"; default: diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifiableRepositoryImpl.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifiableRepositoryImpl.java index 03517664b1..906a97b222 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifiableRepositoryImpl.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifiableRepositoryImpl.java @@ -679,6 +679,7 @@ protected String getWhereClause( return super.getWhereClause(fc, argumentMappings, criterionCount); } + @Override public long retrieveCount(StringBuilder sqlCount, final Map argumentMappings) { long total = dbi.withHandle( @@ -795,6 +796,7 @@ public I retrieveOne( + (StringUtils.hasText(innerSelect) ? innerSelect : tableName) + " AS " + tableAlias + + " " + (sqlSelectAllFieldsJoins != null ? sqlSelectAllFieldsJoins : "") + " LEFT JOIN " + IdentifierRepositoryImpl.TABLE_NAME @@ -847,6 +849,13 @@ public I retrieveOne( @Override public I save(I identifiable, Map bindings) { + return save(identifiable, bindings, null); + } + + public I save( + I identifiable, + Map bindings, + BiFunction, String> sqlModifier) { if (bindings == null) { bindings = new HashMap<>(0); } @@ -857,7 +866,6 @@ public I save(I identifiable, Map bindings) { // split label bindings.put("split_label", splitToArray(identifiable.getLabel())); bindings.put("tags_uuids", extractUuids(identifiable.getTags())); - final Map finalBindings = new HashMap<>(bindings); if (identifiable.getUuid() == null) { // in case of fileresource the uuid is created on binary upload (before metadata save) // to make saving on storage using uuid is possible @@ -870,7 +878,8 @@ public I save(I identifiable, Map bindings) { identifiable.setLastModified(LocalDateTime.now()); } - final String sql = + final String finalSql; + String sql = "INSERT INTO " + tableName + "(" @@ -878,9 +887,16 @@ public I save(I identifiable, Map bindings) { + ") VALUES (" + getSqlInsertValues() + ")"; + if (sqlModifier != null) { + finalSql = sqlModifier.apply(sql, bindings); + } else { + finalSql = sql; + } + + final Map finalBindings = new HashMap<>(bindings); dbi.withHandle( - h -> h.createUpdate(sql).bindMap(finalBindings).bindBean(identifiable).execute()); + h -> h.createUpdate(finalSql).bindMap(finalBindings).bindBean(identifiable).execute()); return identifiable; } @@ -970,6 +986,13 @@ protected boolean supportsCaseSensitivityForProperty(String modelProperty) { @Override public I update(I identifiable, Map bindings) { + return update(identifiable, bindings, null); + } + + public I update( + I identifiable, + Map bindings, + BiFunction, String> sqlModifier) { if (bindings == null) { bindings = new HashMap<>(0); } @@ -979,17 +1002,23 @@ public I update(I identifiable, Map bindings) { // split label bindings.put("split_label", splitToArray(identifiable.getLabel())); bindings.put("tags_uuids", extractUuids(identifiable.getTags())); - final Map finalBindings = new HashMap<>(bindings); identifiable.setLastModified(LocalDateTime.now()); // do not update/left out from statement (not changed since insert): // uuid, created, identifiable_type, identifiable_objecttype, refid - final String sql = - "UPDATE " + tableName + " SET" + getSqlUpdateFieldValues() + " WHERE uuid=:uuid"; + final String finalSql; + String sql = "UPDATE " + tableName + " SET" + getSqlUpdateFieldValues() + " WHERE uuid=:uuid"; + if (sqlModifier != null) { + finalSql = sqlModifier.apply(sql, bindings); + } else { + finalSql = sql; + } + + final Map finalBindings = new HashMap<>(bindings); dbi.withHandle( - h -> h.createUpdate(sql).bindMap(finalBindings).bindBean(identifiable).execute()); + h -> h.createUpdate(finalSql).bindMap(finalBindings).bindBean(identifiable).execute()); return identifiable; } diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/relation/EntityRelationRepositoryImpl.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/relation/EntityRelationRepositoryImpl.java index 69b77c9666..8cd646ed53 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/relation/EntityRelationRepositoryImpl.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/relation/EntityRelationRepositoryImpl.java @@ -20,6 +20,8 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Repository; +// TODO: Neues Feld additional_predicates: UUID[] einführen und befüllen. + @Repository public class EntityRelationRepositoryImpl extends JdbiRepositoryImpl implements EntityRelationRepository { @@ -45,6 +47,15 @@ public void addRelation(UUID subjectEntityUuid, String predicate, UUID objectEnt save(subjectEntityUuid, predicate, objectEntityUuid); } + @Override + public void deleteByObject(UUID objectEntityUuid) { + dbi.withHandle( + h -> + h.createUpdate("DELETE FROM " + tableName + " WHERE object_uuid = :uuid") + .bind("uuid", objectEntityUuid) + .execute()); + } + @Override public void deleteBySubject(UUID subjectEntityUuid) { dbi.withHandle( diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/semantic/SubjectRepositoryImpl.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/semantic/SubjectRepositoryImpl.java index 0e0f27b400..6ea104a7dd 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/semantic/SubjectRepositoryImpl.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/semantic/SubjectRepositoryImpl.java @@ -39,12 +39,13 @@ public class SubjectRepositoryImpl extends JdbiRepositoryImpl implements Subject TABLE_ALIAS, MAPPING_PREFIX); public static final String SQL_FULL_FIELDS_SUBJECTS = SQL_REDUCED_FIELDS_SUBJECTS; - public SubjectRepositoryImpl(Jdbi dbi, CudamiConfig cudamiConfig) { + public SubjectRepositoryImpl( + Jdbi dbi, CudamiConfig cudamiConfig, DbIdentifierMapper dbIdentifierMapper) { super( dbi, TABLE_NAME, TABLE_ALIAS, MAPPING_PREFIX, cudamiConfig.getOffsetForAlternativePaging()); this.dbi.registerRowMapper(BeanMapper.factory(Subject.class, MAPPING_PREFIX)); - this.dbi.registerArrayType(new DbIdentifierMapper()); - this.dbi.registerColumnMapper(Identifier.class, new DbIdentifierMapper()); + this.dbi.registerArrayType(dbIdentifierMapper); + this.dbi.registerColumnMapper(Identifier.class, dbIdentifierMapper); } @Override diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/work/ManifestationRepositoryImpl.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/work/ManifestationRepositoryImpl.java index 11dd13b79c..788d5adce6 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/work/ManifestationRepositoryImpl.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/work/ManifestationRepositoryImpl.java @@ -3,87 +3,344 @@ import de.digitalcollections.cudami.model.config.CudamiConfig; import de.digitalcollections.cudami.server.backend.api.repository.identifiable.entity.work.ManifestationRepository; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.EntityRepositoryImpl; +import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.relation.EntityRelationRepositoryImpl; +import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.semantic.SubjectRepositoryImpl; +import de.digitalcollections.cudami.server.backend.impl.jdbi.type.LocalDateRangeMapper; +import de.digitalcollections.cudami.server.backend.impl.jdbi.type.MainSubTypeMapper.ExpressionTypeMapper; +import de.digitalcollections.cudami.server.backend.impl.jdbi.type.TitleMapper; +import de.digitalcollections.model.RelationSpecification; +import de.digitalcollections.model.identifiable.entity.Entity; +import de.digitalcollections.model.identifiable.entity.relation.EntityRelation; +import de.digitalcollections.model.identifiable.entity.work.ExpressionType; import de.digitalcollections.model.identifiable.entity.work.Manifestation; +import de.digitalcollections.model.identifiable.entity.work.Title; +import de.digitalcollections.model.text.LocalizedText; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import java.util.Vector; +import java.util.function.BiFunction; import org.jdbi.v3.core.Jdbi; +import org.jdbi.v3.core.generic.GenericType; +import org.jdbi.v3.core.result.RowView; import org.springframework.stereotype.Repository; +@SuppressFBWarnings( + value = "VA_FORMAT_STRING_USES_NEWLINE", + justification = "Newline is OK in multiline strings") @Repository public class ManifestationRepositoryImpl extends EntityRepositoryImpl implements ManifestationRepository { - /* THIS IS STILL A BIG TODO! */ + /* THIS IS STILL A BIG TODO! + * + * - ArgumentMapper for + * + * - Publication ✓ + * - Title ✓ + * - MainSubType ✓ + * - DateRange ✓ + * + * - remove involvements trigger ✓ + */ - public static final String TABLE_NAME = "manifestations"; // TODO + public static final String TABLE_NAME = "manifestations"; public static final String TABLE_ALIAS = "mf"; public static final String MAPPING_PREFIX = "mf"; + private EntityRepositoryImpl entityRepository; + @Override public String getSqlInsertFields() { - return super.getSqlInsertFields(); + return super.getSqlInsertFields() + + ", composition, dimensions, expressiontypes" + + ", language, manifestationtype, manufacturingtype" + + ", mediatypes, otherlanguages" + + ", publishingdatepresentation, publishingdaterange, publishing_timevaluerange" + + ", scale, subjects_uuids, version" + + ", work, titles"; } @Override public String getSqlInsertValues() { - return super.getSqlInsertValues(); + return super.getSqlInsertValues() + + ", :composition, :dimensions, :expressionTypes::mainsubtype[]" + + ", :language, :manifestationType, :manufacturingType" + + ", :mediaTypes::varchar[], :otherLanguages::varchar[]" + + ", :publishingDatePresentation, :publishingDateRange::daterange, :publishingTimeValueRange::jsonb" + + ", :scale, :subjects_uuids::UUID[], :version" + + ", :work?.uuid, {{titles}}"; } @Override - public String getSqlSelectAllFields(String tableAlias, String mappingPrefix) { - return getSqlSelectReducedFields(tableAlias, mappingPrefix); + public String getSqlUpdateFieldValues() { + return super.getSqlUpdateFieldValues() + + "composition=:composition, dimensions=:dimensions, expressiontypes=:expressionTypes::mainsubtype[], " + + "language=:language, manifestationtype=:manifestationType, manufacturingtype=:manufacturingType, " + + "mediatypes=:mediaTypes::varchar[], otherlanguages=:otherLanguages::varchar[], " + + "publishingdatepresentation=:publishingDatePresentation, publishingdaterange=:publishingDateRange::daterange, " + + "publishing_timevaluerange=:publishingTimeValueRange::jsonb, scale=:scale, " + + "subjects_uuids=:subjects_uuids::UUID[], version=:version, " + + "work=:work?.uuid, titles={{titles}}"; } @Override - public String getSqlSelectReducedFields(String tableAlias, String mappingPrefix) { - return super.getSqlSelectReducedFields(tableAlias, mappingPrefix); + public String getSqlSelectAllFields(String tableAlias, String mappingPrefix) { + return getSqlSelectReducedFields(tableAlias, mappingPrefix) + + String.format( + """ + , %1$s.composition %2$s_composition, %1$s.dimensions %2$s_dimensions, %1$s.otherlanguages %2$s_otherLanguages, + %1$s.publishingdatepresentation %2$s_publishingDatePresentation, %1$s.publishingdaterange %2$s_publishingDateRange, + %1$s.publishing_timevaluerange %2$s_publishingTimeValueRange, %1$s.scale %2$s_scale, %1$s.version %2$s_version, """, + tableAlias, mappingPrefix) + + SubjectRepositoryImpl.SQL_REDUCED_FIELDS_SUBJECTS; } @Override - public String getSqlUpdateFieldValues() { - return super.getSqlUpdateFieldValues(); + public String getSqlSelectReducedFields(String tableAlias, String mappingPrefix) { + return super.getSqlSelectReducedFields(tableAlias, 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, + """ + .formatted(tableAlias, mappingPrefix) + // parents + + """ + mms.title parent_title, mms.sortKey parent_sortKey, + parent.uuid parent_uuid, parent.label parent_label, parent.titles parent_titles, parent.manifestationtype parent_manifestationType, + """ + .formatted(tableAlias) + // relations + // %1$s.additional_predicates %2$s_additionalPredicates, + + """ + %1$s.predicate %2$s_predicate, %1$s.sortindex %2$s_sortindex, + max(%1$s.sortindex) OVER (PARTITION BY %3$s.uuid) relation_max_sortindex, """ + .formatted( + EntityRelationRepositoryImpl.TABLE_ALIAS, + EntityRelationRepositoryImpl.MAPPING_PREFIX, + tableAlias) + + entityRepository.getSqlSelectReducedFields(); } - public ManifestationRepositoryImpl(Jdbi jdbi, CudamiConfig cudamiConfig) { + public static final String SQL_SELECT_ALL_FIELDS_JOINS = + """ + LEFT JOIN %2$s %3$s ON %3$s.uuid = ANY (%1$s.subjects_uuids) + LEFT JOIN ( + manifestation_manifestations mms INNER JOIN manifestations parent + ON parent.uuid = mms.subject_uuid + ) ON mms.object_uuid = %1$s.uuid + LEFT JOIN ( + %4$s %5$s INNER JOIN %6$s %7$s ON %5$s.subject_uuid = %7$s.uuid + ) ON %5$s.object_uuid = %1$s.uuid + """ + .formatted( + TABLE_ALIAS, + /*2-3*/ SubjectRepositoryImpl.TABLE_NAME, + SubjectRepositoryImpl.TABLE_ALIAS, + /*4-5*/ EntityRelationRepositoryImpl.TABLE_NAME, + EntityRelationRepositoryImpl.TABLE_ALIAS, + /*6-7*/ EntityRepositoryImpl.TABLE_NAME, + EntityRepositoryImpl.TABLE_ALIAS); + + public ManifestationRepositoryImpl( + Jdbi jdbi, + CudamiConfig cudamiConfig, + ExpressionTypeMapper expressionTypeMapper, + LocalDateRangeMapper dateRangeMapper, + TitleMapper titleMapper, + EntityRepositoryImpl entityRepository) { super( jdbi, TABLE_NAME, TABLE_ALIAS, MAPPING_PREFIX, Manifestation.class, + SQL_SELECT_ALL_FIELDS_JOINS, cudamiConfig.getOffsetForAlternativePaging()); + dbi.registerArrayType(expressionTypeMapper); + dbi.registerArgument(dateRangeMapper); + dbi.registerColumnMapper(ExpressionType.class, expressionTypeMapper); + dbi.registerColumnMapper(dateRangeMapper); + dbi.registerColumnMapper(titleMapper); + + this.entityRepository = entityRepository; + } + + private BiFunction, String> buildTitleSql( + final Manifestation manifestation) { + return (sql, bindings) -> { + if (manifestation.getTitles() == null || manifestation.getTitles().isEmpty()) { + return sql.replace("{{titles}}", "NULL"); + } + List titleConstructors = new ArrayList<>(); + for (int i = 0; i < manifestation.getTitles().size(); i++) { + titleConstructors.add( + String.format( + "title_constructor(:titles_%1$d_mainType, :titles_%1$d_subType, " + + ":titles_%1$d_text::jsonb, :titles_%1$d_textLocales::varchar[])", + i)); + Title title = manifestation.getTitles().get(i); + bindings.put( + String.format("titles_%d_mainType", i), + title.getTitleType() != null ? title.getTitleType().getMainType() : null); + bindings.put( + String.format("titles_%d_subType", i), + title.getTitleType() != null ? title.getTitleType().getSubType() : null); + bindings.put(String.format("titles_%d_text", i), title.getText()); + bindings.put( + String.format("titles_%d_textLocales", i), + title.getTextLocalesOfOriginalScripts() != null + ? title.getTextLocalesOfOriginalScripts().stream() + .map(l -> l.toLanguageTag()) + .toArray(n -> new String[n]) + : null); + } + return sql.replace("{{titles}}", "ARRAY[" + String.join(", ", titleConstructors) + "]"); + }; } @Override - public String getColumnName(String modelProperty) { - return super.getColumnName(modelProperty); - // switch (modelProperty) { - // default: - // return super.getColumnName(modelProperty); - // } + protected void extendReducedIdentifiable(Manifestation manifestation, RowView rowView) { + // parents + UUID parentUuid = rowView.getColumn("parent_uuid", UUID.class); + if (parentUuid != null) { + if (manifestation.getParents() == null) { + manifestation.setParents(new ArrayList<>(1)); + } + String parentTitle = rowView.getColumn("parent_title", String.class); + if (!manifestation.getParents().parallelStream() + .anyMatch( + relSpec -> + Objects.equals(relSpec.getSubject().getUuid(), parentUuid) + && Objects.equals(relSpec.getTitle(), parentTitle))) { + Manifestation parent = + Manifestation.builder() + .uuid(parentUuid) + .label(rowView.getColumn("parent_label", LocalizedText.class)) + .titles( + rowView.getColumn( + "parent_titles", + new GenericType>() {})) // TODO could this work?? + .manifestationType(rowView.getColumn("parent_manifestationType", String.class)) + .build(); + manifestation + .getParents() + .add( + RelationSpecification.builder() + .title(parentTitle) + .sortKey(rowView.getColumn("parent_sortKey", String.class)) + .subject(parent) + .build()); + } + } + + // relations + UUID entityUuid = rowView.getColumn(entityRepository.getMappingPrefix() + "_uuid", UUID.class); + if (entityUuid != null) { + if (manifestation.getRelations() == null) { + int maxIndex = rowView.getColumn("relation_max_sortindex", Integer.class); + Vector relations = new Vector<>(maxIndex); + relations.setSize(maxIndex); + manifestation.setRelations(relations); + } + String relationPredicate = + rowView.getColumn( + EntityRelationRepositoryImpl.MAPPING_PREFIX + "_predicate", String.class); + if (!manifestation.getRelations().stream() + .anyMatch( + relation -> + Objects.equals(entityUuid, relation.getSubject().getUuid()) + && Objects.equals(relationPredicate, relation.getPredicate()))) { + Entity relatedEntity = rowView.getRow(Entity.class); + manifestation + .getRelations() + .set( + rowView.getColumn( + EntityRelationRepositoryImpl.MAPPING_PREFIX + "_sortindex", Integer.class), + EntityRelation.builder() + .subject(relatedEntity) + .predicate(relationPredicate) + .additionalPredicates( + rowView.getColumn( + EntityRelationRepositoryImpl.MAPPING_PREFIX + "_additionalPredicates", + new GenericType>() {})) + .build()); + } + } + + // subjects + // TODO } @Override - protected List getSearchTermTemplates(String tableAlias, String originalSearchTerm) { - // TODO Auto-generated method stub - return super.getSearchTermTemplates(tableAlias, originalSearchTerm); + public Manifestation save(Manifestation manifestation, Map bindings) { + if (bindings == null) { + bindings = new HashMap<>(2); + } + bindings.put("subjects_uuids", extractUuids(manifestation.getSubjects())); + return super.save(manifestation, bindings, buildTitleSql(manifestation)); } @Override - protected String addSearchTermMappings(String searchTerm, Map argumentMappings) { - // TODO Auto-generated method stub - return super.addSearchTermMappings(searchTerm, argumentMappings); + public Manifestation update(Manifestation manifestation, Map bindings) { + if (bindings == null) { + bindings = new HashMap<>(2); + } + bindings.put("subjects_uuids", extractUuids(manifestation.getSubjects())); + return super.update(manifestation, bindings, buildTitleSql(manifestation)); + } + + @Override + public String getColumnName(String modelProperty) { + switch (modelProperty) { + case "composition": + case "dimensions": + case "language": + case "scale": + case "titles": + case "version": + case "work": + return modelProperty; + case "expressionTypes": + case "manifestationType": + case "manufacturingType": + case "mediaTypes": + case "otherLanguages": + case "publishingDatePresentation": + case "publishingDateRange": + return modelProperty.toLowerCase(); + case "publishingTimeValueRange": + return "publishing_timevaluerange"; + default: + return super.getColumnName(modelProperty); + } } @Override protected List getAllowedOrderByFields() { - // TODO Auto-generated method stub - return super.getAllowedOrderByFields(); + List orderByFields = super.getAllowedOrderByFields(); + return orderByFields; } @Override protected boolean supportsCaseSensitivityForProperty(String modelProperty) { - // TODO Auto-generated method stub - return super.supportsCaseSensitivityForProperty(modelProperty); + switch (modelProperty) { + case "composition": + case "dimensions": + case "language": + case "manifestationType": + case "manufacturingType": + case "publishingDatePresentation": + case "scale": + case "version": + return true; + default: + return super.supportsCaseSensitivityForProperty(modelProperty); + } } } diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/plugins/JsonbJdbiPlugin.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/plugins/JsonbJdbiPlugin.java index e4714b40fd..dd0693cd23 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/plugins/JsonbJdbiPlugin.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/plugins/JsonbJdbiPlugin.java @@ -9,6 +9,7 @@ import de.digitalcollections.model.identifiable.entity.CustomAttributes; import de.digitalcollections.model.text.LocalizedStructuredContent; import de.digitalcollections.model.text.LocalizedText; +import de.digitalcollections.model.time.TimeValueRange; import de.digitalcollections.model.view.RenderingHints; import de.digitalcollections.model.view.RenderingHintsPreviewImage; import org.jdbi.v3.core.Jdbi; @@ -35,6 +36,7 @@ public void customizeJdbi(Jdbi db) { db.registerArgument(new JsonbArgumentFactory<>(TimeValue.class, objectMapper)); db.registerArgument( new JsonbListArgumentFactory<>(LocalizedStructuredContent.class, objectMapper)); + db.registerArgument(new JsonbArgumentFactory<>(TimeValueRange.class, objectMapper)); // column mapper db.registerColumnMapper(new JsonbColumnMapperFactory(CoordinateLocation.class, objectMapper)); @@ -48,5 +50,6 @@ public void customizeJdbi(Jdbi db) { db.registerColumnMapper(new JsonbColumnMapperFactory(TimeValue.class, objectMapper)); db.registerColumnMapper( new JsonbListColumnMapperFactory(LocalizedStructuredContent.class, objectMapper)); + db.registerColumnMapper(new JsonbColumnMapperFactory(TimeValueRange.class, objectMapper)); } } diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/type/LocalDateRangeMapper.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/type/LocalDateRangeMapper.java new file mode 100644 index 0000000000..b8a25aa835 --- /dev/null +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/type/LocalDateRangeMapper.java @@ -0,0 +1,56 @@ +package de.digitalcollections.cudami.server.backend.impl.jdbi.type; + +import de.digitalcollections.model.time.LocalDateRange; +import java.lang.reflect.Type; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.time.LocalDate; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.jdbi.v3.core.argument.Argument; +import org.jdbi.v3.core.argument.ArgumentFactory; +import org.jdbi.v3.core.config.ConfigRegistry; +import org.jdbi.v3.core.mapper.ColumnMapper; +import org.jdbi.v3.core.statement.StatementContext; + +public class LocalDateRangeMapper implements ArgumentFactory, ColumnMapper { + + public LocalDateRangeMapper() {} + + @Override + public Optional build(Type type, Object value, ConfigRegistry config) { + if (!(value instanceof LocalDateRange)) { + return Optional.empty(); + } + LocalDateRange v = (LocalDateRange) value; + return Optional.of( + (position, statement, ctx) -> { + statement.setString(position, String.format("[%s,%s]", v.getStart(), v.getEnd())); + }); + } + + @Override + public LocalDateRange map(ResultSet r, int columnNumber, StatementContext ctx) + throws SQLException { + String value = r.getString(columnNumber); + Matcher valueParts = + Pattern.compile( + "^(?\\[|\\()(?[\\d-]+),(?[\\d-]+)(?\\]|\\))$") + .matcher(value); + if (!valueParts.find()) { + return null; + } + LocalDate lower = LocalDate.parse(valueParts.group("lower")); + LocalDate upper = LocalDate.parse(valueParts.group("upper")); + if (valueParts.group("lowbound").equals("(")) { + // lower bound is not included so we add one day + lower = lower.plusDays(1); + } + if (valueParts.group("upbound").equals(")")) { + // upper bound is not included so we subtract one day + upper = upper.minusDays(1); + } + return new LocalDateRange(lower, upper); + } +} diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/type/MainSubTypeMapper.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/type/MainSubTypeMapper.java new file mode 100644 index 0000000000..4bb41f5932 --- /dev/null +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/type/MainSubTypeMapper.java @@ -0,0 +1,90 @@ +package de.digitalcollections.cudami.server.backend.impl.jdbi.type; + +import de.digitalcollections.model.MainSubType; +import de.digitalcollections.model.identifiable.entity.work.ExpressionType; +import de.digitalcollections.model.identifiable.entity.work.TitleType; +import java.lang.reflect.InvocationTargetException; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.jdbi.v3.core.array.SqlArrayType; +import org.jdbi.v3.core.mapper.ColumnMapper; +import org.jdbi.v3.core.statement.StatementContext; +import org.springframework.util.StringUtils; + +public class MainSubTypeMapper { + + private Class derivedClass; + + protected MainSubTypeMapper(Class derivedClass) { + this.derivedClass = derivedClass; + } + + public String getTypeName() { + return "mainsubtype"; + } + + public Object convertArrayElement(M element) { + return "(" + + (element.getMainType() != null + ? String.format("\"%s\"", element.getMainType().replaceAll("['\"]", "$0$0")) + : "") + + (element.getSubType() != null + ? String.format(",\"%s\"", element.getSubType().replaceAll("['\"]", "$0$0")) + : ",") + + ")"; + } + + public M createTypeFromString(String value) { + if (!StringUtils.hasText(value)) { + return null; + } + + // \p{Punct} is punctuation including " and \ + Matcher valueParts = + Pattern.compile( + "^\\p{Punct}{0,2}[(]\\p{Punct}{0,2}([\\w\\p{Punct}]*)\\p{Punct}{0,2},\\p{Punct}{0,2}([\\w\\p{Punct}]*)\\p{Punct}{0,2}[)]\\p{Punct}{0,2}$") + .matcher(value); + if (!valueParts.find()) { + return null; + } + M result = null; + try { + result = + derivedClass + .getConstructor(String.class, String.class) + .newInstance(valueParts.group(1), valueParts.group(2)); + } catch (InstantiationException + | IllegalAccessException + | IllegalArgumentException + | InvocationTargetException + | NoSuchMethodException + | SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return result; + } + + public M map(ResultSet r, int columnNumber, StatementContext ctx) throws SQLException { + String value = r.getString(columnNumber); + return createTypeFromString(value); + } + + public static class ExpressionTypeMapper extends MainSubTypeMapper + implements SqlArrayType, ColumnMapper { + + public ExpressionTypeMapper() { + super(ExpressionType.class); + } + } + + public static class TitleTypeMapper extends MainSubTypeMapper + implements SqlArrayType, ColumnMapper { + + public TitleTypeMapper() { + super(TitleType.class); + } + } +} diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/type/TitleMapper.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/type/TitleMapper.java new file mode 100644 index 0000000000..cf585a06fd --- /dev/null +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/backend/impl/jdbi/type/TitleMapper.java @@ -0,0 +1,54 @@ +package de.digitalcollections.cudami.server.backend.impl.jdbi.type; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import de.digitalcollections.model.identifiable.entity.work.Title; +import de.digitalcollections.model.identifiable.entity.work.TitleType; +import de.digitalcollections.model.text.LocalizedText; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Locale; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.jdbi.v3.core.mapper.ColumnMapper; +import org.jdbi.v3.core.statement.StatementContext; + +public class TitleMapper implements ColumnMapper { + + private ObjectMapper objectMapper; + private MainSubTypeMapper.TitleTypeMapper titleTypeMapper; + + public TitleMapper(ObjectMapper objectMapper, MainSubTypeMapper.TitleTypeMapper titleTypeMapper) { + this.objectMapper = objectMapper; + this.titleTypeMapper = titleTypeMapper; + } + + @Override + public Title map(ResultSet r, int columnNumber, StatementContext ctx) throws SQLException { + String value = r.getString(columnNumber); + Matcher valueParts = + Pattern.compile( + "^[(](?<titletype>\\p{Punct}*?[(].+?[)]\\p{Punct}*?),(?<text>\\p{Punct}*?[{].+?[}]\\p{Punct}*?),(?<orig>\\p{Punct}*?[{][\\w,-]+[}]\\p{Punct}*?)[)]$", + Pattern.UNICODE_CHARACTER_CLASS) + .matcher(value); + if (!valueParts.find()) { + return null; + } + TitleType titleType = titleTypeMapper.createTypeFromString(valueParts.group("titletype")); + LocalizedText titleText = null; + try { + titleText = objectMapper.readValue(valueParts.group("text"), LocalizedText.class); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Set<Locale> localesOfOriginalScripts = + Stream.of(valueParts.group("orig").split(",")) + .map(s -> Locale.forLanguageTag(s)) + .collect(Collectors.toSet()); + return new Title(titleText, localesOfOriginalScripts, titleType); + } +} diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/config/SpringConfigBackendDatabase.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/config/SpringConfigBackendDatabase.java index abb48375ea..f01d8d7300 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/config/SpringConfigBackendDatabase.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/java/de/digitalcollections/cudami/server/config/SpringConfigBackendDatabase.java @@ -3,6 +3,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import de.digitalcollections.commons.jdbi.DcCommonsJdbiPlugin; import de.digitalcollections.cudami.server.backend.impl.jdbi.plugins.JsonbJdbiPlugin; +import de.digitalcollections.cudami.server.backend.impl.jdbi.type.DbIdentifierMapper; +import de.digitalcollections.cudami.server.backend.impl.jdbi.type.LocalDateRangeMapper; +import de.digitalcollections.cudami.server.backend.impl.jdbi.type.MainSubTypeMapper; +import de.digitalcollections.cudami.server.backend.impl.jdbi.type.MainSubTypeMapper.TitleTypeMapper; +import de.digitalcollections.cudami.server.backend.impl.jdbi.type.TitleMapper; import de.digitalcollections.model.view.BreadcrumbNode; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList; @@ -70,4 +75,29 @@ public JdbiFactoryBean jdbi(DataSource ds, ObjectMapper objectMapper) { public DataSourceTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } + + @Bean + public DbIdentifierMapper dbIdentifierMapper() { + return new DbIdentifierMapper(); + } + + @Bean + public MainSubTypeMapper.ExpressionTypeMapper expressionTypeMapper() { + return new MainSubTypeMapper.ExpressionTypeMapper(); + } + + @Bean + public MainSubTypeMapper.TitleTypeMapper titleTypeMapper() { + return new MainSubTypeMapper.TitleTypeMapper(); + } + + @Bean + public TitleMapper titleMapper(ObjectMapper objectMapper, TitleTypeMapper titleTypeMapper) { + return new TitleMapper(objectMapper, titleTypeMapper); + } + + @Bean + public LocalDateRangeMapper dateRangeMapper() { + return new LocalDateRangeMapper(); + } } diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.03__DDL_add_sortindex_to_rel_entity_entities.sql b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.03__DDL_add_sortindex_to_rel_entity_entities.sql new file mode 100644 index 0000000000..0be113ca5f --- /dev/null +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.03__DDL_add_sortindex_to_rel_entity_entities.sql @@ -0,0 +1 @@ +ALTER TABLE rel_entity_entities ADD COLUMN IF NOT EXISTS sortindex SMALLINT; diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.04__DDL_drop_manifestations.involvements.sql b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.04__DDL_drop_manifestations.involvements.sql new file mode 100644 index 0000000000..ed46a220d1 --- /dev/null +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.04__DDL_drop_manifestations.involvements.sql @@ -0,0 +1 @@ +ALTER TABLE manifestations DROP COLUMN IF EXISTS involvements_uuids; diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.06__DDL_alter_manifestations.sql b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.06__DDL_alter_manifestations.sql new file mode 100644 index 0000000000..5b976645af --- /dev/null +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.06__DDL_alter_manifestations.sql @@ -0,0 +1,17 @@ +ALTER TABLE manifestations + DROP CONSTRAINT IF EXISTS fk_parent; + +DROP TRIGGER IF EXISTS tr_manifestations_involvements ON manifestations; +DROP TRIGGER IF EXISTS tr_manifestations_series ON manifestations; + +ALTER TABLE manifestations + ADD COLUMN IF NOT EXISTS manifestationtype varchar COLLATE "ucs_basic", + DROP COLUMN IF EXISTS parent, + ADD COLUMN IF NOT EXISTS publishing_timevaluerange jsonb, + DROP COLUMN IF EXISTS series_uuids, + DROP COLUMN IF EXISTS sortkey; + +ALTER TABLE manifestations + DROP CONSTRAINT IF EXISTS fk_previewfileresource, + ADD CONSTRAINT fk_previewfileresource FOREIGN KEY (previewfileresource) REFERENCES fileresources_image; + diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.07__DDL_create_function_title_constructor.sql b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.07__DDL_create_function_title_constructor.sql new file mode 100644 index 0000000000..2713d6cc9a --- /dev/null +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.06.07__DDL_create_function_title_constructor.sql @@ -0,0 +1,13 @@ +CREATE OR REPLACE FUNCTION title_constructor( + title_main_type varchar, title_sub_type varchar, + titletext jsonb, + locales varchar[] +) +RETURNS Title +LANGUAGE plpgsql AS +$body$ +BEGIN + RETURN ROW(ROW(title_main_type, title_sub_type)::mainsubtype, titletext, locales); +END; +$body$; + diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.08.03__DDL_create_table_manifestation_publishers.sql b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.08.03__DDL_create_table_manifestation_publishers.sql new file mode 100644 index 0000000000..660acc973e --- /dev/null +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/main/resources/de/digitalcollections/cudami/server/backend/impl/database/migration/V13.08.03__DDL_create_table_manifestation_publishers.sql @@ -0,0 +1,8 @@ +CREATE TABLE manifestation_publishers ( + manifestation_uuid uuid NOT NULL CONSTRAINT fk_manifestation REFERENCES manifestations, + publisher_uuid uuid NOT NULL CONSTRAINT fk_publisher REFERENCES publishers, + sortKey smallint NOT NULL, + + PRIMARY KEY (manifestation_uuid, publisher_uuid) +); + diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/database/config/SpringConfigBackendDatabase.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/database/config/SpringConfigBackendTestDatabase.java similarity index 82% rename from dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/database/config/SpringConfigBackendDatabase.java rename to dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/database/config/SpringConfigBackendTestDatabase.java index 49a9f94f87..02e08bb3cc 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/database/config/SpringConfigBackendDatabase.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/database/config/SpringConfigBackendTestDatabase.java @@ -4,6 +4,7 @@ import de.digitalcollections.commons.jdbi.DcCommonsJdbiPlugin; import de.digitalcollections.cudami.model.config.CudamiConfig; import de.digitalcollections.cudami.server.backend.impl.jdbi.plugins.JsonbJdbiPlugin; +import de.digitalcollections.cudami.server.config.SpringConfigBackendDatabase; import de.digitalcollections.model.jackson.DigitalCollectionsObjectMapper; import java.util.Map; import javax.sql.DataSource; @@ -14,6 +15,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.junit.jupiter.Container; @@ -22,8 +24,10 @@ @Testcontainers @Configuration -@ComponentScan(basePackages = {"de.digitalcollections.cudami.server.backend.impl.jdbi"}) -public class SpringConfigBackendDatabase { +@ComponentScan( + basePackages = {"de.digitalcollections.cudami.server.backend.impl.jdbi"}, + basePackageClasses = SpringConfigBackendDatabase.class) +public class SpringConfigBackendTestDatabase { private static final DockerImageName DOCKER_IMAGE_NAME = DockerImageName.parse("postgres:12"); private static Boolean isMigrated = false; @@ -37,17 +41,20 @@ public class SpringConfigBackendDatabase { } @Bean + @Primary public PostgreSQLContainer postgreSQLContainer() { return postgreSQLContainer; } @Bean - public ObjectMapper objectMapper() { + @Primary + public ObjectMapper testObjectMapper() { return new DigitalCollectionsObjectMapper(); } @Bean - public DataSource dataSource() { + @Primary + public DataSource testDataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName(postgreSQLContainer.getDriverClassName()); dataSource.setUrl(postgreSQLContainer.getJdbcUrl()); @@ -57,7 +64,8 @@ public DataSource dataSource() { } @Bean - Jdbi jdbi(ObjectMapper objectMapper, DataSource dataSource) { + @Primary + Jdbi testJdbi(ObjectMapper objectMapper, DataSource dataSource) { Jdbi jdbi = Jdbi.create(dataSource); jdbi.installPlugin(new SqlObjectPlugin()); jdbi.installPlugin(new DcCommonsJdbiPlugin()); @@ -83,7 +91,8 @@ Jdbi jdbi(ObjectMapper objectMapper, DataSource dataSource) { } @Bean - CudamiConfig cudamiConfig() { + @Primary + CudamiConfig testCudamiConfig() { var cudamiConfig = new CudamiConfig(null, null, 5000, null); return cudamiConfig; } diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/PublisherRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/PublisherRepositoryImplTest.java index ca9c6b8d6b..eeae50fa25 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/PublisherRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/PublisherRepositoryImplTest.java @@ -4,7 +4,7 @@ import de.digitalcollections.cudami.model.config.CudamiConfig; import de.digitalcollections.cudami.server.backend.api.repository.exceptions.RepositoryException; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.agent.CorporateBodyRepositoryImpl; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.agent.PersonRepositoryImpl; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.geo.location.HumanSettlementRepositoryImpl; @@ -40,7 +40,7 @@ @SpringBootTest( webEnvironment = WebEnvironment.MOCK, classes = {PublisherRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @Sql(scripts = "classpath:cleanup_database.sql") @DisplayName("The Publisher Repository") class PublisherRepositoryImplTest { @@ -199,12 +199,12 @@ void findFilteredAgentLocation() throws RepositoryException { .add( FilterCriterion.builder() .withExpression("agent_uuid") - .isEquals(corporateBody1.getUuid().toString()) + .isEquals(corporateBody1.getUuid()) .build()) .add( FilterCriterion.builder() - .withExpression("location_uuid") - .contains(place1.getUuid().toString()) + .withExpression("location_uuids") + .isEquals(List.of(place1.getUuid())) .build()) .build()) .build()); @@ -239,14 +239,12 @@ void findFilteredAgentMultipleLocations() throws RepositoryException { .add( FilterCriterion.builder() .withExpression("agent_uuid") - .isEquals(corporateBody1.getUuid().toString()) + .isEquals(corporateBody1.getUuid()) .build()) .add( FilterCriterion.builder() .withExpression("location_uuids") - .isEquals( - List.of( - place1.getUuid().toString(), place2.getUuid().toString())) + .isEquals(List.of(place1.getUuid(), place2.getUuid())) .build()) .build()) .build()); @@ -299,7 +297,7 @@ void findWithoutLocations() throws RepositoryException { .add( FilterCriterion.builder() .withExpression("agent_uuid") - .isEquals(corporateBody.getUuid().toString()) + .isEquals(corporateBody.getUuid()) .build()) .build()) .build()); @@ -322,7 +320,7 @@ void findWithoutAgent() throws RepositoryException { .add( FilterCriterion.builder() .withExpression("location_uuids") - .isEquals(List.of(place.getUuid().toString())) + .isEquals(List.of(place.getUuid())) .build()) .build()) .build()); diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifiableRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifiableRepositoryImplTest.java index ba89d5c8f5..47d63ac994 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifiableRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifiableRepositoryImplTest.java @@ -4,7 +4,7 @@ import de.digitalcollections.cudami.model.config.CudamiConfig; import de.digitalcollections.cudami.server.backend.api.repository.identifiable.IdentifiableRepository; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.model.identifiable.Identifiable; import de.digitalcollections.model.identifiable.IdentifiableType; import de.digitalcollections.model.identifiable.entity.DigitalObject; @@ -37,7 +37,7 @@ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.MOCK, classes = IdentifiableRepositoryImpl.class) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @DisplayName("The Identifiable Repository") @Sql(scripts = "classpath:cleanup_database.sql") class IdentifiableRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifierRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifierRepositoryImplTest.java index b63377544b..60883109f9 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifierRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifierRepositoryImplTest.java @@ -5,7 +5,7 @@ import de.digitalcollections.cudami.model.config.CudamiConfig; import de.digitalcollections.cudami.server.backend.api.repository.exceptions.RepositoryException; import de.digitalcollections.cudami.server.backend.api.repository.identifiable.web.WebpageRepository; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.model.identifiable.Identifier; import de.digitalcollections.model.identifiable.web.Webpage; import java.util.List; @@ -26,7 +26,7 @@ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.MOCK, classes = IdentifiableRepositoryImpl.class) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @DisplayName("The Identifier Repository") @Sql(scripts = "classpath:cleanup_database.sql") class IdentifierRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifierTypeRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifierTypeRepositoryImplTest.java index 967ff20f76..b9c6882cbb 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifierTypeRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/IdentifierTypeRepositoryImplTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.model.identifiable.IdentifierType; import de.digitalcollections.model.list.paging.PageRequest; import de.digitalcollections.model.list.paging.PageResponse; @@ -23,7 +23,7 @@ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.MOCK, classes = IdentifiableRepositoryImpl.class) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) // FIXME After `digitalobjects` is merged into main: @Sql(scripts = // "classpath:cleanup_database.sql") @DisplayName("The IdentifierType Repository") diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/alias/UrlAliasRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/alias/UrlAliasRepositoryImplTest.java index d45d27b269..e65d3fd2eb 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/alias/UrlAliasRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/alias/UrlAliasRepositoryImplTest.java @@ -10,7 +10,7 @@ import de.digitalcollections.cudami.server.backend.api.repository.exceptions.UrlAliasRepositoryException; import de.digitalcollections.cudami.server.backend.api.repository.identifiable.entity.WebsiteRepository; import de.digitalcollections.cudami.server.backend.api.repository.identifiable.web.WebpageRepository; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.model.identifiable.IdentifiableObjectType; import de.digitalcollections.model.identifiable.IdentifiableType; import de.digitalcollections.model.identifiable.alias.LocalizedUrlAliases; @@ -45,7 +45,7 @@ @ExtendWith(SpringExtension.class) @SpringBootTest(webEnvironment = WebEnvironment.MOCK, classes = UrlAliasRepositoryImpl.class) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @DisplayName("The UrlAlias Repository") @TestInstance(Lifecycle.PER_CLASS) @TestMethodOrder(MethodOrderer.OrderAnnotation.class) diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/DigitalObjectRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/DigitalObjectRepositoryImplTest.java index 36fde7d504..47b0f0b992 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/DigitalObjectRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/DigitalObjectRepositoryImplTest.java @@ -5,7 +5,7 @@ import de.digitalcollections.cudami.model.config.CudamiConfig; import de.digitalcollections.cudami.server.backend.api.repository.exceptions.RepositoryException; import de.digitalcollections.cudami.server.backend.api.repository.identifiable.entity.work.ItemRepository; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.IdentifierRepositoryImpl; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.agent.CorporateBodyRepositoryImpl; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.agent.PersonRepositoryImpl; @@ -66,7 +66,7 @@ @SpringBootTest( webEnvironment = WebEnvironment.MOCK, classes = {DigitalObjectRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @DisplayName("The DigitalObject Repository") @TestMethodOrder(MethodOrderer.OrderAnnotation.class) class DigitalObjectRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/WebsiteRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/WebsiteRepositoryImplTest.java index 460608e7a2..4651e516a2 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/WebsiteRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/WebsiteRepositoryImplTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.web.WebpageRepositoryImpl; import de.digitalcollections.model.identifiable.entity.EntityType; import de.digitalcollections.model.identifiable.entity.Website; @@ -30,7 +30,7 @@ @SpringBootTest( webEnvironment = WebEnvironment.MOCK, classes = {WebsiteRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @Sql(scripts = "classpath:cleanup_database.sql") @DisplayName("The Website Repository") class WebsiteRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/agent/AgentRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/agent/AgentRepositoryImplTest.java index be54181cf7..9facca8534 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/agent/AgentRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/agent/AgentRepositoryImplTest.java @@ -3,7 +3,7 @@ import static de.digitalcollections.cudami.server.backend.impl.asserts.CudamiAssertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.model.identifiable.entity.agent.Agent; import de.digitalcollections.model.text.LocalizedText; import java.util.Locale; @@ -25,13 +25,16 @@ @SpringBootTest( webEnvironment = WebEnvironment.MOCK, classes = {AgentRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @Sql(scripts = "classpath:cleanup_database.sql") @DisplayName("The Agent Repository") class AgentRepositoryImplTest { AgentRepositoryImpl<Agent> repo; + private static final Locale LOCALE_ZH_HANI = + new Locale.Builder().setLanguage("zh").setScript("Hani").build(); + @Autowired CudamiConfig cudamiConfig; @Autowired PostgreSQLContainer postgreSQLContainer; @@ -58,8 +61,13 @@ void testCreate() { void testUpdate() { Agent agent = repo.save(Agent.builder().label("Test").addName("some name").build()); agent.setLabel("changed test"); - agent.setName(new LocalizedText(Locale.ENGLISH, "some english name")); - agent.setNameLocalesOfOriginalScripts(Set.of(Locale.ENGLISH)); + LocalizedText name = + LocalizedText.builder() + .text(Locale.ENGLISH, "some english name") + .text(LOCALE_ZH_HANI, "難經辨眞") + .build(); + agent.setName(name); + agent.setNameLocalesOfOriginalScripts(Set.of(Locale.ENGLISH, LOCALE_ZH_HANI)); Agent saved = repo.update(agent); Agent actual = repo.getByUuid(saved.getUuid()); diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/agent/CorporateBodyRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/agent/CorporateBodyRepositoryImplTest.java index f022a91378..af0e5b2932 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/agent/CorporateBodyRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/agent/CorporateBodyRepositoryImplTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.model.identifiable.entity.agent.CorporateBody; import de.digitalcollections.model.list.filtering.FilterCriterion; import de.digitalcollections.model.list.filtering.FilterOperation; @@ -28,7 +28,7 @@ @SpringBootTest( webEnvironment = WebEnvironment.MOCK, classes = {CorporateBodyRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @Sql(scripts = "classpath:cleanup_database.sql") @DisplayName("The CorporateBody Repository") class CorporateBodyRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/relation/EntityRelationRepositoryTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/relation/EntityRelationRepositoryTest.java index c0baaf9734..bade7b35f7 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/relation/EntityRelationRepositoryTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/relation/EntityRelationRepositoryTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.EntityRepositoryImpl; import de.digitalcollections.cudami.server.backend.impl.jdbi.relation.PredicateRepositoryImpl; import de.digitalcollections.cudami.server.backend.impl.model.TestModelFixture; @@ -32,7 +32,7 @@ @SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = EntityRelationRepositoryImpl.class) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @DisplayName("The EntityRelationRepository") public class EntityRelationRepositoryTest { EntityRelationRepositoryImpl repository; diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/semantic/SubjectRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/semantic/SubjectRepositoryImplTest.java index 937847d414..a83d8240fb 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/semantic/SubjectRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/semantic/SubjectRepositoryImplTest.java @@ -3,7 +3,8 @@ import static org.assertj.core.api.Assertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; +import de.digitalcollections.cudami.server.backend.impl.jdbi.type.DbIdentifierMapper; import de.digitalcollections.model.identifiable.Identifier; import de.digitalcollections.model.list.filtering.FilterCriterion; import de.digitalcollections.model.list.filtering.Filtering; @@ -33,7 +34,7 @@ @SpringBootTest( webEnvironment = WebEnvironment.MOCK, classes = {SubjectRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @Sql(scripts = "classpath:cleanup_database.sql") @DisplayName("The Subject Repository") class SubjectRepositoryImplTest { @@ -46,9 +47,11 @@ class SubjectRepositoryImplTest { @Autowired Jdbi jdbi; + @Autowired DbIdentifierMapper dbIdentifierMapper; + @BeforeEach public void beforeEach() { - repo = new SubjectRepositoryImpl(jdbi, cudamiConfig); + repo = new SubjectRepositoryImpl(jdbi, cudamiConfig, dbIdentifierMapper); } @Test diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/work/ItemRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/work/ItemRepositoryImplTest.java index ff74d3805f..290e65aa58 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/work/ItemRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/work/ItemRepositoryImplTest.java @@ -7,7 +7,7 @@ import de.digitalcollections.cudami.server.backend.api.repository.identifiable.entity.agent.AgentRepository; import de.digitalcollections.cudami.server.backend.api.repository.identifiable.entity.agent.CorporateBodyRepository; import de.digitalcollections.cudami.server.backend.api.repository.identifiable.entity.agent.PersonRepository; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.DigitalObjectRepositoryImpl; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.agent.AgentRepositoryImpl; import de.digitalcollections.model.identifiable.IdentifiableObjectType; @@ -41,7 +41,7 @@ @SpringBootTest( webEnvironment = WebEnvironment.MOCK, classes = {ItemRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @DisplayName("The Item Repository Test") public class ItemRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/work/ManifestationRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/work/ManifestationRepositoryImplTest.java new file mode 100644 index 0000000000..958667e598 --- /dev/null +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/entity/work/ManifestationRepositoryImplTest.java @@ -0,0 +1,103 @@ +package de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.work; + +import static org.assertj.core.api.Assertions.assertThat; + +import de.digitalcollections.cudami.server.backend.api.repository.PublisherRepository; +import de.digitalcollections.cudami.server.backend.api.repository.exceptions.RepositoryException; +import de.digitalcollections.cudami.server.backend.api.repository.identifiable.entity.agent.CorporateBodyRepository; +import de.digitalcollections.cudami.server.backend.api.repository.identifiable.entity.geo.location.HumanSettlementRepository; +import de.digitalcollections.cudami.server.backend.api.repository.relation.PredicateRepository; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; +import de.digitalcollections.model.identifiable.entity.agent.CorporateBody; +import de.digitalcollections.model.identifiable.entity.relation.EntityRelation; +import de.digitalcollections.model.identifiable.entity.work.ExpressionType; +import de.digitalcollections.model.identifiable.entity.work.Manifestation; +import de.digitalcollections.model.identifiable.entity.work.Title; +import de.digitalcollections.model.identifiable.entity.work.TitleType; +import de.digitalcollections.model.relation.Predicate; +import de.digitalcollections.model.text.LocalizedText; +import de.digitalcollections.model.time.LocalDateRange; +import java.time.LocalDate; +import java.util.Locale; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.testcontainers.containers.PostgreSQLContainer; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = ManifestationRepositoryImpl.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) +@DisplayName("The Manifestation Repository") +@Sql(scripts = "classpath:cleanup_database.sql") +class ManifestationRepositoryImplTest { + + @Autowired PostgreSQLContainer postgreSQLContainer; + @Autowired ManifestationRepositoryImpl repo; + + @Autowired CorporateBodyRepository corporateBodyRepository; + @Autowired HumanSettlementRepository humanSettlementRepository; + @Autowired PublisherRepository publisherRepository; + @Autowired PredicateRepository predicateRepository; + + @Test + @DisplayName("is testable") + void containerIsUpAndRunning() { + assertThat(postgreSQLContainer.isRunning()).isTrue(); + } + + @Test + void testSaveManifestationMapOfStringObject() throws RepositoryException { + CorporateBody editor = CorporateBody.builder().label("Editor").addName("Editor").build(); + editor = corporateBodyRepository.save(editor); + CorporateBody someoneElse = + CorporateBody.builder().label("Someone else").addName("Someone else").build(); + someoneElse = corporateBodyRepository.save(someoneElse); + + Predicate isEditorOf = + predicateRepository.save(Predicate.builder().value("is_editor_of").build()); + Predicate isSomethingElseOf = + predicateRepository.save(Predicate.builder().value("is_somethingelse_of").build()); + + Manifestation manifestation = + Manifestation.builder() + .label(Locale.GERMAN, "ein Label") + .composition("composition") + .expressionType(ExpressionType.builder().mainType("BOOK").subType("PRINT").build()) + .language(Locale.GERMAN) + .mediaType("BOOK") + // .publisher(publisher) + .publishingDateRange(new LocalDateRange(LocalDate.of(2020, 1, 15), LocalDate.now())) + .title( + Title.builder() + .text(new LocalizedText(Locale.GERMAN, "Ein deutscher Titel")) + .titleType(new TitleType("main", "main")) + .textLocaleOfOriginalScript(Locale.GERMAN) + .textLocaleOfOriginalScript(Locale.ENGLISH) + .build()) + .title( + Title.builder() + .text(new LocalizedText(Locale.GERMAN, "Untertitel")) + .titleType(new TitleType("main", "sub")) + .textLocaleOfOriginalScript(Locale.GERMAN) + .build()) + .build(); + manifestation.addRelation(new EntityRelation(editor, "is_editor_of", manifestation)); + manifestation.addRelation( + new EntityRelation(someoneElse, "is_somethingelse_of", manifestation)); + Manifestation saved = repo.save(manifestation); + + // we add the relations manually, actually done by the service + // TODO + + Manifestation actual = repo.getByUuid(saved.getUuid()); + // assertThat(actual).isEqualTo(saved); + } + + @Test + void testUpdateManifestationMapOfStringObject() {} +} diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/resource/DigitalObjectLinkedDataFileResourceRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/resource/DigitalObjectLinkedDataFileResourceRepositoryImplTest.java index 399a96c0ae..f50e55bfbf 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/resource/DigitalObjectLinkedDataFileResourceRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/resource/DigitalObjectLinkedDataFileResourceRepositoryImplTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.DigitalObjectRepositoryImpl; import de.digitalcollections.model.file.MimeType; import de.digitalcollections.model.identifiable.entity.DigitalObject; @@ -29,7 +29,7 @@ @SpringBootTest( webEnvironment = WebEnvironment.MOCK, classes = {DigitalObjectLinkedDataFileResourceRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @Sql(scripts = "classpath:cleanup_database.sql") @DisplayName("The DigitalObjectLinkedDataFileResource Repository") class DigitalObjectLinkedDataFileResourceRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/resource/DigitalObjectRenderingFileResourceRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/resource/DigitalObjectRenderingFileResourceRepositoryImplTest.java index 2780080703..c742567192 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/resource/DigitalObjectRenderingFileResourceRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/identifiable/resource/DigitalObjectRenderingFileResourceRepositoryImplTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.cudami.server.backend.impl.jdbi.identifiable.entity.DigitalObjectRepositoryImpl; import de.digitalcollections.model.file.MimeType; import de.digitalcollections.model.identifiable.entity.DigitalObject; @@ -30,7 +30,7 @@ @SpringBootTest( webEnvironment = WebEnvironment.MOCK, classes = {DigitalObjectRenderingFileResourceRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @Sql(scripts = "classpath:cleanup_database.sql") @DisplayName("The DigitalObjectRenderingFileResource Repository") class DigitalObjectRenderingFileResourceRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/legal/LicenseRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/legal/LicenseRepositoryImplTest.java index 3f22497f8c..4e95cd8f2b 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/legal/LicenseRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/legal/LicenseRepositoryImplTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.cudami.server.backend.impl.model.TestModelFixture; import de.digitalcollections.model.legal.License; import de.digitalcollections.model.list.paging.PageRequest; @@ -29,7 +29,7 @@ @SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = {LicenseRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @DisplayName("Test for License Repository") @Sql(scripts = "classpath:cleanup_database.sql") public class LicenseRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/security/UserRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/security/UserRepositoryImplTest.java index e7003b6f83..e6ca988298 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/security/UserRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/security/UserRepositoryImplTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.model.list.paging.PageRequest; import de.digitalcollections.model.list.paging.PageResponse; import de.digitalcollections.model.security.User; @@ -23,7 +23,7 @@ @SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = UserRepositoryImpl.class) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @DisplayName("The User Repository") public class UserRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/semantic/HeadwordRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/semantic/HeadwordRepositoryImplTest.java index 34a966c82e..647a50822f 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/semantic/HeadwordRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/semantic/HeadwordRepositoryImplTest.java @@ -4,7 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.model.list.buckets.Bucket; import de.digitalcollections.model.list.buckets.BucketsRequest; import de.digitalcollections.model.list.buckets.BucketsResponse; @@ -28,7 +28,7 @@ @SpringBootTest( webEnvironment = WebEnvironment.MOCK, classes = {HeadwordRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @Sql(scripts = "classpath:cleanup_database.sql") @DisplayName("The Website Repository") class HeadwordRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/semantic/TagRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/semantic/TagRepositoryImplTest.java index cd90d1cb31..7da571b4f9 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/semantic/TagRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/semantic/TagRepositoryImplTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.model.list.filtering.FilterCriterion; import de.digitalcollections.model.list.filtering.Filtering; import de.digitalcollections.model.list.paging.PageRequest; @@ -31,7 +31,7 @@ @SpringBootTest( webEnvironment = WebEnvironment.MOCK, classes = {TagRepositoryImpl.class}) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @Sql(scripts = "classpath:cleanup_database.sql") @DisplayName("The Tag Repository") class TagRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/view/RenderingTemplateRepositoryImplTest.java b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/view/RenderingTemplateRepositoryImplTest.java index 2a899d973d..88c2fbebca 100644 --- a/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/view/RenderingTemplateRepositoryImplTest.java +++ b/dc-cudami-server/dc-cudami-server-backend-jdbi/src/test/java/de/digitalcollections/cudami/server/backend/impl/jdbi/view/RenderingTemplateRepositoryImplTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import de.digitalcollections.cudami.model.config.CudamiConfig; -import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendDatabase; +import de.digitalcollections.cudami.server.backend.impl.database.config.SpringConfigBackendTestDatabase; import de.digitalcollections.model.list.paging.PageRequest; import de.digitalcollections.model.list.paging.PageResponse; import de.digitalcollections.model.view.RenderingTemplate; @@ -23,7 +23,7 @@ @SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes = RenderingTemplateRepositoryImpl.class) -@ContextConfiguration(classes = SpringConfigBackendDatabase.class) +@ContextConfiguration(classes = SpringConfigBackendTestDatabase.class) @DisplayName("The RenderingTemplate Repository") public class RenderingTemplateRepositoryImplTest { diff --git a/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/api/service/identifiable/entity/relation/EntityRelationService.java b/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/api/service/identifiable/entity/relation/EntityRelationService.java index 523dbfb72d..19a15a8477 100644 --- a/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/api/service/identifiable/entity/relation/EntityRelationService.java +++ b/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/api/service/identifiable/entity/relation/EntityRelationService.java @@ -1,5 +1,6 @@ package de.digitalcollections.cudami.server.business.api.service.identifiable.entity.relation; +import de.digitalcollections.cudami.server.business.api.service.exceptions.CudamiServiceException; import de.digitalcollections.model.identifiable.entity.Entity; import de.digitalcollections.model.identifiable.entity.relation.EntityRelation; import de.digitalcollections.model.list.paging.PageRequest; @@ -22,6 +23,12 @@ default void deleteBySubject(Entity subjectEntity) { void deleteBySubject(UUID subjectEntityUuid); + default void deleteByObject(Entity objectEntity) { + deleteByObject(objectEntity.getUuid()); + } + + void deleteByObject(UUID objectEntityUuid); + /** * Get paged, sorted, filtered relations * @@ -42,5 +49,5 @@ default List<EntityRelation> getBySubject(Entity subjectEntity) { * @param entityRelations a list of entity relations to persist * @return the persisted list of entity relations */ - List<EntityRelation> save(List<EntityRelation> entityRelations); + List<EntityRelation> save(List<EntityRelation> entityRelations) throws CudamiServiceException; } diff --git a/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/alias/UrlAliasServiceImpl.java b/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/alias/UrlAliasServiceImpl.java index 8dd6ca8e2a..028177a8a4 100644 --- a/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/alias/UrlAliasServiceImpl.java +++ b/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/alias/UrlAliasServiceImpl.java @@ -351,7 +351,11 @@ public void validate(LocalizedUrlAliases localizedUrlAliases) throws ValidationE + ", website=" + u.getWebsite() + ", target=" - + u.getTargetUuid()); + + u.getTargetUuid() + + " in " + + tuples + + " of " + + localizedUrlAliases); } else { tuples.add(key); } diff --git a/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/entity/relation/EntityRelationServiceImpl.java b/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/entity/relation/EntityRelationServiceImpl.java index 9edb5752f4..2ca37247db 100644 --- a/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/entity/relation/EntityRelationServiceImpl.java +++ b/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/entity/relation/EntityRelationServiceImpl.java @@ -1,6 +1,7 @@ package de.digitalcollections.cudami.server.business.impl.service.identifiable.entity.relation; import de.digitalcollections.cudami.server.backend.api.repository.identifiable.entity.relation.EntityRelationRepository; +import de.digitalcollections.cudami.server.business.api.service.exceptions.CudamiServiceException; import de.digitalcollections.cudami.server.business.api.service.identifiable.entity.relation.EntityRelationService; import de.digitalcollections.model.identifiable.entity.relation.EntityRelation; import de.digitalcollections.model.list.paging.PageRequest; @@ -32,6 +33,11 @@ public void deleteBySubject(UUID subjectEntityUuid) { repository.deleteBySubject(subjectEntityUuid); } + @Override + public void deleteByObject(UUID objectEntityUuid) { + repository.deleteByObject(objectEntityUuid); + } + @Override public PageResponse<EntityRelation> find(PageRequest pageRequest) { return repository.find(pageRequest); @@ -43,7 +49,16 @@ public List<EntityRelation> getBySubject(UUID subjectEntityUuid) { } @Override - public List<EntityRelation> save(List<EntityRelation> entityRelations) { - return repository.save(entityRelations); + public List<EntityRelation> save(List<EntityRelation> entityRelations) + throws CudamiServiceException { + // We assume, that all referenced predicates, the "normal" and the additional ones + // are already available in the service. If not, the repository would throw + // a ForeignKey exception + try { + return repository.save(entityRelations); + } catch (Exception e) { + throw new CudamiServiceException( + "Cannot persist EntityRelations " + entityRelations + ": " + e, e); + } } } diff --git a/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/entity/work/ManifestationServiceImpl.java b/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/entity/work/ManifestationServiceImpl.java index 1659eb4dd0..7a5905ac3c 100644 --- a/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/entity/work/ManifestationServiceImpl.java +++ b/dc-cudami-server/dc-cudami-server-business/src/main/java/de/digitalcollections/cudami/server/business/impl/service/identifiable/entity/work/ManifestationServiceImpl.java @@ -3,24 +3,34 @@ import de.digitalcollections.cudami.model.config.CudamiConfig; import de.digitalcollections.cudami.server.backend.api.repository.identifiable.entity.work.ManifestationRepository; import de.digitalcollections.cudami.server.business.api.service.LocaleService; +import de.digitalcollections.cudami.server.business.api.service.exceptions.CudamiServiceException; +import de.digitalcollections.cudami.server.business.api.service.exceptions.IdentifiableServiceException; +import de.digitalcollections.cudami.server.business.api.service.exceptions.ValidationException; import de.digitalcollections.cudami.server.business.api.service.identifiable.IdentifierService; import de.digitalcollections.cudami.server.business.api.service.identifiable.alias.UrlAliasService; +import de.digitalcollections.cudami.server.business.api.service.identifiable.entity.relation.EntityRelationService; import de.digitalcollections.cudami.server.business.api.service.identifiable.entity.work.ManifestationService; import de.digitalcollections.cudami.server.business.impl.service.identifiable.entity.EntityServiceImpl; import de.digitalcollections.cudami.server.config.HookProperties; +import de.digitalcollections.model.identifiable.entity.relation.EntityRelation; import de.digitalcollections.model.identifiable.entity.work.Manifestation; +import java.util.List; +import java.util.stream.Collectors; import org.springframework.stereotype.Service; @Service public class ManifestationServiceImpl extends EntityServiceImpl<Manifestation> implements ManifestationService { + private EntityRelationService entityRelationService; + public ManifestationServiceImpl( ManifestationRepository repository, IdentifierService identifierService, UrlAliasService urlAliasService, HookProperties hookProperties, LocaleService localeService, + EntityRelationService entityRealationService, CudamiConfig cudamiConfig) { super( repository, @@ -29,5 +39,55 @@ public ManifestationServiceImpl( hookProperties, localeService, cudamiConfig); + this.entityRelationService = entityRealationService; + } + + @Override + public Manifestation save(Manifestation manifestation) + throws IdentifiableServiceException, ValidationException { + Manifestation savedManifestation = super.save(manifestation); + try { + savedManifestation = persistEntityRelations(savedManifestation, true); + } catch (CudamiServiceException e) { + throw new IdentifiableServiceException( + "Cannot save Manifestation=" + manifestation + ": " + e, e); + } + return savedManifestation; + } + + @Override + public Manifestation update(Manifestation manifestation) + throws IdentifiableServiceException, ValidationException { + Manifestation updatedManifestation = super.update(manifestation); + try { + updatedManifestation = persistEntityRelations(updatedManifestation, false); + } catch (CudamiServiceException e) { + throw new IdentifiableServiceException( + "Cannot update Manifestation=" + manifestation + ": " + e, e); + } + return updatedManifestation; + } + + private Manifestation persistEntityRelations(Manifestation manifestation, boolean deleteExisting) + throws CudamiServiceException { + if (deleteExisting) { + // Check, if there are already persisted EntityRelations for the manifestation + // If yes, delete them + entityRelationService.deleteByObject(manifestation); + } + + // save all entity relations and set the UUID of the object + List<EntityRelation> relations = + manifestation.getRelations().stream() + .map( + r -> { + r.setObject(manifestation); + return r; + }) + .collect(Collectors.toList()); + relations = entityRelationService.save(relations); + manifestation.setRelations(relations); + + return manifestation; } } diff --git a/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/PublisherController.java b/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/PublisherController.java index c8c4b7a3d6..8b147a783c 100644 --- a/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/PublisherController.java +++ b/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/PublisherController.java @@ -51,8 +51,6 @@ public PageResponse<Publisher> find( @RequestParam(name = "searchTerm", required = false) String searchTerm, @RequestParam(name = "agent_uuid", required = false) FilterCriterion<UUID> filterCriterionAgentUuid, - @RequestParam(name = "location_uuid", required = false) - FilterCriterion<UUID> filterCriterionLocationUuid, @RequestParam(name = "location_uuids", required = false) String rawFilterCriterionLocationUuids, @RequestParam(name = "publisherPresentation", required = false) @@ -73,14 +71,6 @@ public PageResponse<Publisher> find( filtering.add(filterCriterionAgentUuid); } - if (filterCriterionLocationUuid != null) { - if (filtering == null) { - filtering = new Filtering(); - } - filterCriterionLocationUuid.setExpression("location_uuid"); - filtering.add(filterCriterionLocationUuid); - } - if (rawFilterCriterionLocationUuids != null) { if (filtering == null) { filtering = new Filtering(); diff --git a/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/identifiable/entity/relation/EntityRelationController.java b/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/identifiable/entity/relation/EntityRelationController.java index b7a4901879..42cca80bce 100644 --- a/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/identifiable/entity/relation/EntityRelationController.java +++ b/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/identifiable/entity/relation/EntityRelationController.java @@ -1,5 +1,6 @@ package de.digitalcollections.cudami.server.controller.identifiable.entity.relation; +import de.digitalcollections.cudami.server.business.api.service.exceptions.CudamiServiceException; import de.digitalcollections.cudami.server.business.api.service.identifiable.entity.relation.EntityRelationService; import de.digitalcollections.model.identifiable.entity.relation.EntityRelation; import de.digitalcollections.model.list.filtering.FilterCriterion; @@ -68,7 +69,8 @@ public PageResponse<EntityRelation> findByPredicate( */ List<EntityRelation> saveEntityRelationsForSubject( @PathVariable("subjectuuid") UUID subjectUuid, - @RequestBody List<EntityRelation> entityRelations) { + @RequestBody List<EntityRelation> entityRelations) + throws CudamiServiceException { if (!subjectUuid.equals(entityRelations.get(0).getSubject().getUuid())) { throw new IllegalArgumentException( "Mismatching arguments. SubjectUuid must match the Uuid of the subject of the first item"); @@ -85,7 +87,8 @@ List<EntityRelation> saveEntityRelationsForSubject( "/latest/entities/relations" }, produces = MediaType.APPLICATION_JSON_VALUE) - List<EntityRelation> save(@RequestBody List<EntityRelation> entityRelations) { + List<EntityRelation> save(@RequestBody List<EntityRelation> entityRelations) + throws CudamiServiceException { return entityRelationService.save(entityRelations); } } diff --git a/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/relation/PredicateController.java b/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/relation/PredicateController.java index 63ec073e4a..e1cc85c734 100644 --- a/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/relation/PredicateController.java +++ b/dc-cudami-server/dc-cudami-server-webapp/src/main/java/de/digitalcollections/cudami/server/controller/relation/PredicateController.java @@ -6,10 +6,12 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import java.util.List; +import java.util.UUID; +import javax.validation.constraints.NotNull; import org.springframework.http.MediaType; -import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @@ -19,6 +21,8 @@ public class PredicateController { private final PredicateService predicateService; + private static final String REGEX_UUID = + "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"; public PredicateController(PredicateService predicateService) { this.predicateService = predicateService; @@ -30,20 +34,59 @@ public List<Predicate> getAll() { return predicateService.getAll(); } - @Operation(summary = "create or update a predicate, identified by its value") + @Operation(summary = "Get a predicate by its value") + @GetMapping( + value = {"/v6/predicates/{value}"}, + produces = MediaType.APPLICATION_JSON_VALUE) + public Predicate getByValue(@PathVariable("value") String value) { + return predicateService.getByValue(value); + } + + /* + Since we cannot use .* als "fallback" mapping (Spring reports "ambigious handler methods"), we + must evaluate the parameter manually + */ + @Operation(summary = "create or update a predicate, identified either by its value or by uuid") @PutMapping( value = { - "/v6/predicates/{value}", - "/v5/predicates/{value}", - "/v3/predicates/{value}", - "/latest/predicates/{value}" + "/v6/predicates/{valueOrUuid:.+}", + "/v5/predicates/{valueOrUuid:.+}", + "/v3/predicates/{valueOrUuid:.+}", + "/latest/predicates/{valueOrUuid:.+}" }, produces = MediaType.APPLICATION_JSON_VALUE) public Predicate update( - @PathVariable("value") String value, @RequestBody Predicate predicate, BindingResult errors) + @PathVariable("valueOrUuid") String valueOrUuid, @NotNull @RequestBody Predicate predicate) throws PredicatesServiceException { - if (value == null || predicate == null || !value.equals(predicate.getValue())) { - throw new IllegalArgumentException("value of path does not match value of predicate"); + + if (valueOrUuid.matches(REGEX_UUID)) { + UUID uuid = UUID.fromString(valueOrUuid); + if (!predicate.getUuid().equals(uuid)) { + throw new IllegalArgumentException( + "path value of uuid=" + + uuid + + " does not match uuid of predicate=" + + predicate.getUuid()); + } + return predicateService.save(predicate); + } + + String value = valueOrUuid; + if (!value.matches(predicate.getValue())) { + throw new IllegalArgumentException( + "value of path=" + value + " does not match value of predicate=" + predicate.getValue()); + } + + return predicateService.save(predicate); + } + + @Operation(summary = "saves a predicate") + @PostMapping( + value = {"/v6/predicates", "/v5/predicates", "/v3/predicates", "/latest/predicates"}, + produces = MediaType.APPLICATION_JSON_VALUE) + public Predicate save(@RequestBody Predicate predicate) throws PredicatesServiceException { + if (predicate == null || predicate.getValue() == null) { + throw new IllegalArgumentException("Invalid predicate: " + predicate); } return predicateService.save(predicate); diff --git a/dc-cudami-server/dc-cudami-server-webapp/src/main/resources/application-typedeclarations.yml b/dc-cudami-server/dc-cudami-server-webapp/src/main/resources/application-typedeclarations.yml index f299ecfe56..7325f349cc 100644 --- a/dc-cudami-server/dc-cudami-server-webapp/src/main/resources/application-typedeclarations.yml +++ b/dc-cudami-server/dc-cudami-server-webapp/src/main/resources/application-typedeclarations.yml @@ -5,8 +5,11 @@ cudami: - PRINT - HANDMADE - mediaTypes: #TODO + mediaTypes: - BOOK + - ISSUE + - NEWSPAPER + - SERIAL subjectTypes: - BY @@ -19,6 +22,7 @@ cudami: - TOPIC tagTypes: + - GENRE - IDENTIFIER - SHELFGROUP diff --git a/dc-cudami-server/dc-cudami-server-webapp/src/test/java/de/digitalcollections/cudami/server/controller/BaseControllerTest.java b/dc-cudami-server/dc-cudami-server-webapp/src/test/java/de/digitalcollections/cudami/server/controller/BaseControllerTest.java index 85807443a6..268a0e4fbd 100644 --- a/dc-cudami-server/dc-cudami-server-webapp/src/test/java/de/digitalcollections/cudami/server/controller/BaseControllerTest.java +++ b/dc-cudami-server/dc-cudami-server-webapp/src/test/java/de/digitalcollections/cudami/server/controller/BaseControllerTest.java @@ -197,9 +197,15 @@ protected void testPutJson(String path, String jsonBody, String expectedJsonPath */ protected void testPutJsonWithState(String path, String jsonBody, int expectedState) throws Exception { - mockMvc - .perform(put(path).contentType(MediaType.APPLICATION_JSON).content(jsonBody)) - .andExpect(status().is(expectedState)); + if (jsonBody != null) { + mockMvc + .perform(put(path).contentType(MediaType.APPLICATION_JSON).content(jsonBody)) + .andExpect(status().is(expectedState)); + } else { + mockMvc + .perform(put(path).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().is(expectedState)); + } } /** diff --git a/dc-cudami-server/dc-cudami-server-webapp/src/test/java/de/digitalcollections/cudami/server/controller/PublisherControllerTest.java b/dc-cudami-server/dc-cudami-server-webapp/src/test/java/de/digitalcollections/cudami/server/controller/PublisherControllerTest.java index 5b13e190e7..e72b5c3cd7 100644 --- a/dc-cudami-server/dc-cudami-server-webapp/src/test/java/de/digitalcollections/cudami/server/controller/PublisherControllerTest.java +++ b/dc-cudami-server/dc-cudami-server-webapp/src/test/java/de/digitalcollections/cudami/server/controller/PublisherControllerTest.java @@ -148,8 +148,8 @@ public void filterOneAgentOneLocation() throws Exception { .build()) .add( FilterCriterion.builder() - .withExpression("location_uuid") - .isEquals(locationUuid) + .withExpression("location_uuids") + .isEquals(List.of(locationUuid)) .build()) .build()) .build(); @@ -157,7 +157,7 @@ public void filterOneAgentOneLocation() throws Exception { testHttpGetWithExpectedStatus( "/v6/publishers?pageSize=1&pageNumber=0&agent_uuid=eq:" + agentUuid - + "&location_uuid=eq:" + + "&location_uuids=eq:" + locationUuid, 200); ArgumentCaptor<PageRequest> pageRequestArgumentCaptor = diff --git a/dc-cudami-server/dc-cudami-server-webapp/src/test/java/de/digitalcollections/cudami/server/controller/relation/PredicateControllerTest.java b/dc-cudami-server/dc-cudami-server-webapp/src/test/java/de/digitalcollections/cudami/server/controller/relation/PredicateControllerTest.java new file mode 100644 index 0000000000..a9845e8dd4 --- /dev/null +++ b/dc-cudami-server/dc-cudami-server-webapp/src/test/java/de/digitalcollections/cudami/server/controller/relation/PredicateControllerTest.java @@ -0,0 +1,128 @@ +package de.digitalcollections.cudami.server.controller.relation; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import de.digitalcollections.cudami.server.business.api.service.relation.PredicateService; +import de.digitalcollections.cudami.server.controller.BaseControllerTest; +import de.digitalcollections.model.relation.Predicate; +import de.digitalcollections.model.text.LocalizedText; +import java.util.Locale; +import java.util.UUID; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; + +@WebMvcTest(PredicateController.class) +@DisplayName("The PredicateController") +class PredicateControllerTest extends BaseControllerTest { + + @MockBean private PredicateService predicateService; + + @DisplayName("can save a predicate without UUID") + @Test + public void save() throws Exception { + UUID uuid = UUID.fromString("bb5885f6-fd24-48e9-99f6-1f1a49d239bf"); + Predicate predicate = + Predicate.builder() + .value("foo") + .label(new LocalizedText(Locale.ROOT, "bar")) + .uuid(uuid) + .build(); + + // We save a predicate without UUID + String jsonBody = + "{\"objectType\":\"PREDICATE\",\"value\":\"foo\",\"label\": {" + "\"\": \"bar\"" + "}}"; + + when(predicateService.save(any(Predicate.class))).thenReturn(predicate); + + testPostJson("/v6/predicates", jsonBody, "/v6/relation/predicates/predicates_response.json"); + testPostJson("/v5/predicates", jsonBody, "/v6/relation/predicates/predicates_response.json"); + testPostJson("/v3/predicates", jsonBody, "/v6/relation/predicates/predicates_response.json"); + testPostJson( + "/latest/predicates", jsonBody, "/v6/relation/predicates/predicates_response.json"); + } + + @DisplayName( + "can save a predicate without UUID but with value in path (old style, where save and update were equal)") + @Test + public void saveWithValueInPath() throws Exception { + UUID uuid = UUID.fromString("bb5885f6-fd24-48e9-99f6-1f1a49d239bf"); + Predicate predicate = + Predicate.builder() + .value("foo") + .label(new LocalizedText(Locale.ROOT, "bar")) + .uuid(uuid) + .build(); + + // We save a predicate without UUID + String jsonBody = + "{\"objectType\":\"PREDICATE\",\"value\":\"foo\",\"label\": {" + "\"\": \"bar\"" + "}}"; + + when(predicateService.save(any(Predicate.class))).thenReturn(predicate); + + // Yes, it really works with put! + testPutJson("/v6/predicates/foo", jsonBody, "/v6/relation/predicates/predicates_response.json"); + testPutJson("/v5/predicates/foo", jsonBody, "/v6/relation/predicates/predicates_response.json"); + testPutJson("/v3/predicates/foo", jsonBody, "/v6/relation/predicates/predicates_response.json"); + testPutJson( + "/latest/predicates/foo", jsonBody, "/v6/relation/predicates/predicates_response.json"); + } + + @DisplayName("can update a predicate by its value, without uuid (used by old clients)") + @Test + public void updateByValueWithoutUuid() throws Exception { + UUID uuid = UUID.fromString("bb5885f6-fd24-48e9-99f6-1f1a49d239bf"); + Predicate predicate = + Predicate.builder() + .value("foo") + .label(new LocalizedText(Locale.ROOT, "bar")) + .uuid(uuid) + .build(); + + // We update a predicate without UUID + String jsonBody = + "{\"objectType\":\"PREDICATE\",\"value\":\"foo\",\"label\": {" + "\"\": \"bar\"" + "}}"; + when(predicateService.save(any(Predicate.class))).thenReturn(predicate); + + testPutJson("/v6/predicates/foo", jsonBody, "/v6/relation/predicates/predicates_response.json"); + } + + @DisplayName("can update a predicate by its uuid") + @Test + public void updateByUuid() throws Exception { + UUID uuid = UUID.fromString("bb5885f6-fd24-48e9-99f6-1f1a49d239bf"); + Predicate predicate = + Predicate.builder() + .value("foo") + .label(new LocalizedText(Locale.ROOT, "bar")) + .uuid(uuid) + .build(); + + // We update a predicate without UUID + String jsonBody = + "{\"uuid\":\"" + + uuid + + "\",\"objectType\":\"PREDICATE\",\"value\":\"foo\",\"label\": {" + + "\"\": \"bar\"" + + "}}"; + when(predicateService.save(any(Predicate.class))).thenReturn(predicate); + + testPutJson( + "/v6/predicates/" + uuid, jsonBody, "/v6/relation/predicates/predicates_response.json"); + } + + @DisplayName( + "throws an error (since there's no valid PUT endpoint), when update is called without uuid or value") + @Test + public void exceptionForEmptyPathOnUpdate() throws Exception { + testPutJsonWithState("/v6/predicates/", "{}", 500); + } + + @DisplayName("throws an error, when update is called without predicate") + @Test + public void exceptionForEmptyPredicateOnUpdate() throws Exception { + testPutJsonWithState("/v6/predicates/foo", null, 500); + } +} diff --git a/dc-cudami-server/dc-cudami-server-webapp/src/test/resources/json/v6/relation/predicates/predicates_response.json b/dc-cudami-server/dc-cudami-server-webapp/src/test/resources/json/v6/relation/predicates/predicates_response.json new file mode 100644 index 0000000000..c8b851b439 --- /dev/null +++ b/dc-cudami-server/dc-cudami-server-webapp/src/test/resources/json/v6/relation/predicates/predicates_response.json @@ -0,0 +1,8 @@ +{ + "objectType": "PREDICATE", + "uuid": "bb5885f6-fd24-48e9-99f6-1f1a49d239bf", + "label": { + "": "bar" + }, + "value": "foo" +} \ No newline at end of file