diff --git a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java index f4d1cebb3..f662b21a7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java +++ b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java @@ -51,4 +51,9 @@ public class AuditableAction { public static final EventId DescriptionTemplate_GetXml = new EventId(8006, "DescriptionTemplate_GetXml"); public static final EventId DescriptionTemplate_Import = new EventId(8007, "DescriptionTemplate_Import"); + public static final EventId SupportiveMaterial_Query = new EventId(9000, "SupportiveMaterial_Query"); + public static final EventId SupportiveMaterial_Lookup = new EventId(9001, "SupportiveMaterial_Lookup"); + public static final EventId SupportiveMaterial_Persist = new EventId(9002, "SupportiveMaterial_Persist"); + public static final EventId SupportiveMaterial_Delete = new EventId(9003, "SupportiveMaterial_Delete"); + } diff --git a/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java b/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java index c2b37d20d..1f67d0a30 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java +++ b/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java @@ -50,7 +50,11 @@ public final class Permission { public static String CloneDmpBlueprint = "CloneDmpBlueprint"; public static String ExportDmpBlueprint = "ExportDmpBlueprint"; public static String ImportDmpBlueprint = "ImportDmpBlueprint"; - + + //DmpDescriptionTemplate + public static String BrowseDmpDescriptionTemplate = "BrowseDmpDescriptionTemplate"; + public static String EditDmpDescriptionTemplate = "EditDmpDescriptionTemplate"; + public static String DeleteDmpDescriptionTemplate = "DeleteDmpDescriptionTemplate"; //Description public static String BrowseDescription = "BrowseDescription"; @@ -82,9 +86,15 @@ public final class Permission { public static String EditDmpReference = "EditDmpReference"; public static String DeleteDmpReference = "DeleteDmpReference"; + //DescriptionReference public static String BrowseDescriptionReference = "BrowseDescriptionReference"; public static String EditDescriptionReference = "EditDescriptionReference"; public static String DeleteDescriptionReference = "DeleteDescriptionReference"; + //SupportiveMaterial + public static String BrowseSupportiveMaterial = "BrowseSupportiveMaterial"; + public static String EditSupportiveMaterial= "EditSupportiveMaterial"; + public static String DeleteSupportiveMaterial = "DeleteSupportiveMaterial"; + } diff --git a/dmp-backend/core/src/main/java/eu/eudat/cache/deposit/RepositoryDepositConfigurationCache.java b/dmp-backend/core/src/main/java/eu/eudat/cache/deposit/RepositoryDepositConfigurationCache.java new file mode 100644 index 000000000..904bf2e3d --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/cache/deposit/RepositoryDepositConfigurationCache.java @@ -0,0 +1,21 @@ +package eu.eudat.cache.deposit; + + +import eu.eudat.configurations.deposit.DepositCacheOptions; +import eu.eudat.model.doi.RepositoryConfigs; +import gr.cite.tools.cache.CacheService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class RepositoryDepositConfigurationCache extends CacheService { + @Autowired + public RepositoryDepositConfigurationCache(DepositCacheOptions options) { + super(options); + } + + @Override + protected Class valueClass() { + return RepositoryConfigs.class; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/configurations/DepositConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/configurations/DepositConfiguration.java deleted file mode 100644 index 23c2dfacc..000000000 --- a/dmp-backend/core/src/main/java/eu/eudat/configurations/DepositConfiguration.java +++ /dev/null @@ -1,50 +0,0 @@ -package eu.eudat.configurations; - -import eu.eudat.depositinterface.repository.RepositoryDeposit; -import eu.eudat.repository.DepositRepository; -import gr.cite.commons.web.oidc.apikey.ApiKeyCacheService; -import gr.cite.commons.web.oidc.apikey.webflux.ApiKeyExchangeFilterFunction; -import gr.cite.commons.web.oidc.apikey.webflux.ApiKeyWebfluxModel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.reactive.function.client.WebClient; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; - -@Configuration -@EnableConfigurationProperties({DepositProperties.class}) -public class DepositConfiguration { - private static final Logger logger = LoggerFactory.getLogger(DepositConfiguration.class); - - private final DepositProperties properties; - - private final ApiKeyCacheService apiKeyCacheService; - - @Autowired - public DepositConfiguration(DepositProperties properties, ApiKeyCacheService apiKeyCacheService) { - this.properties = properties; - this.apiKeyCacheService = apiKeyCacheService; - } - - @Bean - @Qualifier("depositClients") - public List depositClients() { - List clients = new ArrayList<>(); - for (DepositProperties.DepositSource source: properties.getSources()) { - - String host = URI.create(source.getUrl()).getHost(); - ApiKeyWebfluxModel apiKeyWebfluxModel = new ApiKeyWebfluxModel(host + "_" + source.getClientId(), source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope()); - ApiKeyExchangeFilterFunction apiKeyExchangeFilterFunction = new ApiKeyExchangeFilterFunction(this.apiKeyCacheService, apiKeyWebfluxModel); - - clients.add(new DepositRepository(WebClient.builder().baseUrl(source.getUrl() + "/api/deposit").filters(exchangeFilterFunctions -> exchangeFilterFunctions.add(apiKeyExchangeFilterFunction)).build())); - } - return clients; - } -} diff --git a/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositCacheOptions.java b/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositCacheOptions.java new file mode 100644 index 000000000..6b673806f --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositCacheOptions.java @@ -0,0 +1,9 @@ +package eu.eudat.configurations.deposit; + +import gr.cite.tools.cache.CacheOptions; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@ConfigurationProperties(prefix = "cache.deposit") +public class DepositCacheOptions extends CacheOptions { +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositConfiguration.java new file mode 100644 index 000000000..804107ac8 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositConfiguration.java @@ -0,0 +1,9 @@ +package eu.eudat.configurations.deposit; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties({DepositProperties.class, DepositCacheOptions.class}) +public class DepositConfiguration { +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/configurations/DepositProperties.java b/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositProperties.java similarity index 97% rename from dmp-backend/core/src/main/java/eu/eudat/configurations/DepositProperties.java rename to dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositProperties.java index 162d1fd52..819fb90a7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/configurations/DepositProperties.java +++ b/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositProperties.java @@ -1,4 +1,4 @@ -package eu.eudat.configurations; +package eu.eudat.configurations.deposit; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.bind.ConstructorBinding; diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/DmpDescriptionTemplateEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/DmpDescriptionTemplateEntity.java new file mode 100644 index 000000000..72504384b --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/DmpDescriptionTemplateEntity.java @@ -0,0 +1,109 @@ +package eu.eudat.data; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.converters.enums.IsActiveConverter; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +import java.time.Instant; +import java.util.UUID; + +@Table(name = "\"DmpDescriptionTemplate\"") +public class DmpDescriptionTemplateEntity { + + @Id + @Column(name = "id", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID id; + + public static final String _id = "id"; + + @Column(name = "dmp", columnDefinition = "uuid", nullable = false) + private UUID dmp; + + public static final String _dmp = "dmp"; + + @Column(name = "description_template", columnDefinition = "uuid", nullable = false) + private UUID descriptionTemplate; + + public static final String _descriptionTemplate = "descriptionTemplate"; + + @Column(name = "section_id") + private UUID sectionId; + + public static final String _sectionId = "sectionId"; + + @Column(name = "created_at", nullable = false) + private Instant createdAt; + + public static final String _createdAt = "createdAt"; + + @Column(name = "updated_at", nullable = false) + private Instant updatedAt; + + public static final String _updatedAt = "updatedAt"; + + @Column(name = "is_active", nullable = false) + @Convert(converter = IsActiveConverter.class) + private IsActive isActive; + + public static final String _isActive = "isActive"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UUID getDmp() { + return dmp; + } + + public void setDmp(UUID dmp) { + this.dmp = dmp; + } + + public UUID getDescriptionTemplate() { + return descriptionTemplate; + } + + public void setDescriptionTemplate(UUID descriptionTemplate) { + this.descriptionTemplate = descriptionTemplate; + } + + public UUID getSectionId() { + return sectionId; + } + + public void setSectionId(UUID sectionId) { + this.sectionId = sectionId; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + + public IsActive getIsActive() { + return isActive; + } + + public void setIsActive(IsActive isActive) { + this.isActive = isActive; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/DmpReferenceEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/DmpReferenceEntity.java index ded6a3c48..7dc8894ca 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/DmpReferenceEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/DmpReferenceEntity.java @@ -1,9 +1,8 @@ package eu.eudat.data; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.converters.enums.IsActiveConverter; +import jakarta.persistence.*; import java.time.Instant; import java.util.UUID; @@ -27,6 +26,7 @@ public class DmpReferenceEntity { @Column(name = "data") private String data; + public static final String _data = "data"; @Column(name = "created_at", nullable = false) private Instant createdAt; @@ -36,7 +36,10 @@ public class DmpReferenceEntity { private Instant updatedAt; public static final String _updatedAt = "updatedAt"; - public static final String _data = "data"; + @Column(name = "is_active", nullable = false) + @Convert(converter = IsActiveConverter.class) + private IsActive isActive; + public static final String _isActive = "isActive"; public UUID getId() { return id; @@ -85,4 +88,12 @@ public class DmpReferenceEntity { public void setUpdatedAt(Instant updatedAt) { this.updatedAt = updatedAt; } + + public IsActive getIsActive() { + return isActive; + } + + public void setIsActive(IsActive isActive) { + this.isActive = isActive; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/SupportiveMaterialEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/SupportiveMaterialEntity.java new file mode 100644 index 000000000..6131a7868 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/SupportiveMaterialEntity.java @@ -0,0 +1,102 @@ +package eu.eudat.data; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.enums.SupportiveMaterialFieldType; +import eu.eudat.data.converters.enums.IsActiveConverter; +import eu.eudat.data.converters.enums.SupportiveMaterialFieldTypeConverter; +import jakarta.persistence.*; + +import java.time.Instant; +import java.util.UUID; + +@Entity +@Table(name = "\"SupportiveMaterial\"") +public class SupportiveMaterialEntity { + + @Id + @Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false) + private UUID id; + public static final String _id = "id"; + + @Column(name = "type", nullable = false) + @Convert(converter = SupportiveMaterialFieldTypeConverter.class) + private SupportiveMaterialFieldType type; + public static final String _type = "type"; + + @Column(name = "language_code", length = 20, nullable = false) + private String languageCode; + public static final String _languageCode = "languageCode"; + + @Column(name = "payload", nullable = false) + private String payload; + public static final String _payload = "payload"; + + @Column(name = "\"created_at\"", nullable = false) + private Instant createdAt; + public static final String _createdAt = "createdAt"; + + @Column(name = "\"updated_at\"", nullable = false) + private Instant updatedAt; + public static final String _updatedAt = "updatedAt"; + + @Column(name = "is_active", nullable = false) + @Convert(converter = IsActiveConverter.class) + private IsActive isActive; + public static final String _isActive = "isActive"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public SupportiveMaterialFieldType getType() { + return type; + } + + public void setType(SupportiveMaterialFieldType type) { + this.type = type; + } + + public String getLanguageCode() { + return languageCode; + } + + public void setLanguageCode(String languageCode) { + this.languageCode = languageCode; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + + public IsActive getIsActive() { + return isActive; + } + + public void setIsActive(IsActive isActive) { + this.isActive = isActive; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/SupportiveMaterialFieldTypeConverter.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/SupportiveMaterialFieldTypeConverter.java new file mode 100644 index 000000000..b308b5ae8 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/SupportiveMaterialFieldTypeConverter.java @@ -0,0 +1,11 @@ +package eu.eudat.data.converters.enums; + +import eu.eudat.commons.enums.SupportiveMaterialFieldType; +import jakarta.persistence.Converter; + +@Converter +public class SupportiveMaterialFieldTypeConverter extends DatabaseEnumConverter { + public SupportiveMaterialFieldType of(Short i) { + return SupportiveMaterialFieldType.of(i); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/errorcode/ErrorThesaurusProperties.java b/dmp-backend/core/src/main/java/eu/eudat/errorcode/ErrorThesaurusProperties.java index 929ae2a8f..53b6cd926 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/errorcode/ErrorThesaurusProperties.java +++ b/dmp-backend/core/src/main/java/eu/eudat/errorcode/ErrorThesaurusProperties.java @@ -54,4 +54,14 @@ public class ErrorThesaurusProperties { public void setDescriptionTemplateNewVersionConflict(ErrorDescription descriptionTemplateNewVersionConflict) { DescriptionTemplateNewVersionConflict = descriptionTemplateNewVersionConflict; } + + private ErrorDescription dmpNewVersionConflict; + + public ErrorDescription getDmpNewVersionConflict() { + return dmpNewVersionConflict; + } + + public void setDmpNewVersionConflict(ErrorDescription dmpNewVersionConflict) { + this.dmpNewVersionConflict = dmpNewVersionConflict; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/DmpDescriptionTemplate.java b/dmp-backend/core/src/main/java/eu/eudat/model/DmpDescriptionTemplate.java new file mode 100644 index 000000000..ebe2db5e5 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/DmpDescriptionTemplate.java @@ -0,0 +1,94 @@ +package eu.eudat.model; + +import eu.eudat.commons.enums.IsActive; + +import java.time.Instant; +import java.util.UUID; + +public class DmpDescriptionTemplate { + + private UUID id; + + public static final String _id = "id"; + + private Dmp dmp; + + public static final String _dmp = "dmp"; + + private DescriptionTemplate descriptionTemplate; + + public static final String _descriptionTemplate = "descriptionTemplate"; + + private UUID sectionId; + + public static final String _sectionId = "sectionId"; + + private Instant createdAt; + + public static final String _createdAt = "createdAt"; + + private Instant updatedAt; + + public static final String _updatedAt = "updatedAt"; + + private IsActive isActive; + + public static final String _isActive = "isActive"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public Dmp getDmp() { + return dmp; + } + + public void setDmp(Dmp dmp) { + this.dmp = dmp; + } + + public DescriptionTemplate getDescriptionTemplate() { + return descriptionTemplate; + } + + public void setDescriptionTemplate(DescriptionTemplate descriptionTemplate) { + this.descriptionTemplate = descriptionTemplate; + } + + public UUID getSectionId() { + return sectionId; + } + + public void setSectionId(UUID sectionId) { + this.sectionId = sectionId; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + + public IsActive getIsActive() { + return isActive; + } + + public void setIsActive(IsActive isActive) { + this.isActive = isActive; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/SupportiveMaterial.java b/dmp-backend/core/src/main/java/eu/eudat/model/SupportiveMaterial.java new file mode 100644 index 000000000..ca552da3b --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/SupportiveMaterial.java @@ -0,0 +1,88 @@ +package eu.eudat.model; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.enums.SupportiveMaterialFieldType; + +import java.time.Instant; +import java.util.UUID; + + +public class SupportiveMaterial { + + private UUID id; + public static final String _id = "id"; + + private SupportiveMaterialFieldType type; + public static final String _type = "type"; + + private String languageCode; + public static final String _languageCode = "languageCode"; + + private String payload; + public static final String _payload = "payload"; + + private Instant createdAt; + public static final String _createdAt = "createdAt"; + + private Instant updatedAt; + public static final String _updatedAt = "updatedAt"; + + private IsActive isActive; + public static final String _isActive = "isActive"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public SupportiveMaterialFieldType getType() { + return type; + } + + public void setType(SupportiveMaterialFieldType type) { + this.type = type; + } + + public String getLanguageCode() { + return languageCode; + } + + public void setLanguageCode(String languageCode) { + this.languageCode = languageCode; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + + public IsActive getIsActive() { + return isActive; + } + + public void setIsActive(IsActive isActive) { + this.isActive = isActive; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/DescriptionReferenceBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/DescriptionReferenceBuilder.java index c6bebd52f..1b4c5a0fe 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/DescriptionReferenceBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/DescriptionReferenceBuilder.java @@ -38,7 +38,7 @@ public class DescriptionReferenceBuilder extends BaseBuilder { + + private final BuilderFactory builderFactory; + + private final QueryFactory queryFactory; + + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + @Autowired + public DmpDescriptionTemplateBuilder( + ConventionService conventionService, + BuilderFactory builderFactory, QueryFactory queryFactory) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(DmpDescriptionTemplateBuilder.class))); + this.builderFactory = builderFactory; + this.queryFactory = queryFactory; + } + + public DmpDescriptionTemplateBuilder authorize(EnumSet values) { + this.authorize = values; + return this; + } + + @Override + public List build(FieldSet fields, List data) throws MyApplicationException { + this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0)); + this.logger.trace(new DataLogEntry("requested fields", fields)); + if (fields == null || data == null || fields.isEmpty()) + return new ArrayList<>(); + + FieldSet templateFields = fields.extractPrefixed(this.asPrefix(DmpDescriptionTemplate._descriptionTemplate)); + Map templateItemsMap = this.collectTemplates(templateFields, data); + + FieldSet dmpFields = fields.extractPrefixed(this.asPrefix(DmpDescriptionTemplate._dmp)); + Map dmpItemsMap = this.collectDmps(dmpFields, data); + + List models = new ArrayList<>(); + for (DmpDescriptionTemplateEntity d : data) { + DmpDescriptionTemplate m = new DmpDescriptionTemplate(); + if (fields.hasField(this.asIndexer(DmpDescriptionTemplate._id))) + m.setId(d.getId()); + if (fields.hasField(this.asIndexer(DmpDescriptionTemplate._sectionId))) + m.setSectionId(d.getSectionId()); + if (fields.hasField(this.asIndexer(DmpDescriptionTemplate._createdAt))) + m.setCreatedAt(d.getCreatedAt()); + if (fields.hasField(this.asIndexer(DmpDescriptionTemplate._updatedAt))) + m.setUpdatedAt(d.getUpdatedAt()); + if (!templateFields.isEmpty() && templateItemsMap != null && templateItemsMap.containsKey(d.getDescriptionTemplate())) { + m.setDescriptionTemplate(templateItemsMap.get(d.getDescriptionTemplate())); + } + if (!dmpFields.isEmpty() && dmpItemsMap != null && dmpItemsMap.containsKey(d.getDmp())) { + m.setDmp(dmpItemsMap.get(d.getDmp())); + } + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } + + private Map collectTemplates(FieldSet fields, List data) throws MyApplicationException { + if (fields.isEmpty() || data.isEmpty()) + return null; + this.logger.debug("checking related - {}", DescriptionTemplate.class.getSimpleName()); + + Map itemMap; + if (!fields.hasOtherField(this.asIndexer(DescriptionTemplate._id))) { + itemMap = this.asEmpty( + data.stream().map(DmpDescriptionTemplateEntity::getDescriptionTemplate).distinct().collect(Collectors.toList()), + x -> { + DescriptionTemplate item = new DescriptionTemplate(); + item.setId(x); + return item; + }, + DescriptionTemplate::getId); + } else { + FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(DescriptionTemplate._id); + DescriptionTemplateQuery q = this.queryFactory.query(DescriptionTemplateQuery.class).authorize(this.authorize).ids(data.stream().map(DmpDescriptionTemplateEntity::getDescriptionTemplate).distinct().collect(Collectors.toList())); + itemMap = this.builderFactory.builder(DescriptionTemplateBuilder.class).authorize(this.authorize).asForeignKey(q, clone, DescriptionTemplate::getId); + } + if (!fields.hasField(DescriptionTemplate._id)) { + itemMap.values().stream().filter(Objects::nonNull).peek(x -> x.setId(null)).collect(Collectors.toList()); + } + + return itemMap; + } + + private Map collectDmps(FieldSet fields, List data) throws MyApplicationException { + if (fields.isEmpty() || data.isEmpty()) + return null; + this.logger.debug("checking related - {}", Dmp.class.getSimpleName()); + + Map itemMap; + if (!fields.hasOtherField(this.asIndexer(Dmp._id))) { + itemMap = this.asEmpty( + data.stream().map(DmpDescriptionTemplateEntity::getDmp).distinct().collect(Collectors.toList()), + x -> { + Dmp item = new Dmp(); + item.setId(x); + return item; + }, + Dmp::getId); + } else { + FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(Dmp._id); + DmpQuery q = this.queryFactory.query(DmpQuery.class).authorize(this.authorize).ids(data.stream().map(DmpDescriptionTemplateEntity::getDmp).distinct().collect(Collectors.toList())); + itemMap = this.builderFactory.builder(DmpBuilder.class).authorize(this.authorize).asForeignKey(q, clone, Dmp::getId); + } + if (!fields.hasField(Dmp._id)) { + itemMap.values().stream().filter(Objects::nonNull).peek(x -> x.setId(null)).collect(Collectors.toList()); + } + + return itemMap; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpReferenceBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpReferenceBuilder.java index 35995dabc..67f1f44d0 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpReferenceBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/DmpReferenceBuilder.java @@ -26,10 +26,12 @@ import java.util.stream.Collectors; @Component @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class DmpReferenceBuilder extends BaseBuilder{ +public class DmpReferenceBuilder extends BaseBuilder { private final BuilderFactory builderFactory; + private final QueryFactory queryFactory; + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); @Autowired @@ -52,6 +54,7 @@ public class DmpReferenceBuilder extends BaseBuilder(); + FieldSet referenceFields = fields.extractPrefixed(this.asPrefix(DmpReference._reference)); Map referenceItemsMap = this.collectReferences(referenceFields, data); @@ -61,14 +64,18 @@ public class DmpReferenceBuilder extends BaseBuilder models = new ArrayList<>(); for (DmpReferenceEntity d : data) { DmpReference m = new DmpReference(); - if (fields.hasField(this.asIndexer(DmpReference._id))) m.setId(d.getId()); - if (fields.hasField(this.asIndexer(DmpReference._data))) m.setData(d.getData()); - if (fields.hasField(this.asIndexer(DmpReference._createdAt))) m.setCreatedAt(d.getCreatedAt()); - if (fields.hasField(this.asIndexer(DmpReference._updatedAt))) m.setUpdatedAt(d.getUpdatedAt()); - if(!referenceFields.isEmpty() && referenceItemsMap != null && referenceItemsMap.containsKey(d.getReferenceId())){ + if (fields.hasField(this.asIndexer(DmpReference._id))) + m.setId(d.getId()); + if (fields.hasField(this.asIndexer(DmpReference._data))) + m.setData(d.getData()); + if (fields.hasField(this.asIndexer(DmpReference._createdAt))) + m.setCreatedAt(d.getCreatedAt()); + if (fields.hasField(this.asIndexer(DmpReference._updatedAt))) + m.setUpdatedAt(d.getUpdatedAt()); + if (!referenceFields.isEmpty() && referenceItemsMap != null && referenceItemsMap.containsKey(d.getReferenceId())) { m.setReference(referenceItemsMap.get(d.getReferenceId())); } - if(!dmpFields.isEmpty() && dmpItemsMap != null && dmpItemsMap.containsKey(d.getDmpId())){ + if (!dmpFields.isEmpty() && dmpItemsMap != null && dmpItemsMap.containsKey(d.getDmpId())) { m.setDmp(dmpItemsMap.get(d.getDmpId())); } models.add(m); @@ -78,13 +85,14 @@ public class DmpReferenceBuilder extends BaseBuilder collectReferences(FieldSet fields, List data) throws MyApplicationException { - if (fields.isEmpty() || data.isEmpty()) return null; + if (fields.isEmpty() || data.isEmpty()) + return null; this.logger.debug("checking related - {}", Reference.class.getSimpleName()); Map itemMap; if (!fields.hasOtherField(this.asIndexer(Reference._id))) { itemMap = this.asEmpty( - data.stream().map(x -> x.getReferenceId()).distinct().collect(Collectors.toList()), + data.stream().map(DmpReferenceEntity::getReferenceId).distinct().collect(Collectors.toList()), x -> { Reference item = new Reference(); item.setId(x); @@ -93,7 +101,7 @@ public class DmpReferenceBuilder extends BaseBuilder x.getReferenceId()).distinct().collect(Collectors.toList())); + ReferenceQuery q = this.queryFactory.query(ReferenceQuery.class).authorize(this.authorize).ids(data.stream().map(DmpReferenceEntity::getReferenceId).distinct().collect(Collectors.toList())); itemMap = this.builderFactory.builder(ReferenceBuilder.class).authorize(this.authorize).asForeignKey(q, clone, Reference::getId); } if (!fields.hasField(Reference._id)) { @@ -104,13 +112,14 @@ public class DmpReferenceBuilder extends BaseBuilder collectDmps(FieldSet fields, List data) throws MyApplicationException { - if (fields.isEmpty() || data.isEmpty()) return null; + if (fields.isEmpty() || data.isEmpty()) + return null; this.logger.debug("checking related - {}", Dmp.class.getSimpleName()); Map itemMap; if (!fields.hasOtherField(this.asIndexer(Dmp._id))) { itemMap = this.asEmpty( - data.stream().map(x -> x.getDmpId()).distinct().collect(Collectors.toList()), + data.stream().map(DmpReferenceEntity::getDmpId).distinct().collect(Collectors.toList()), x -> { Dmp item = new Dmp(); item.setId(x); @@ -119,7 +128,7 @@ public class DmpReferenceBuilder extends BaseBuilder x.getDmpId()).distinct().collect(Collectors.toList())); + DmpQuery q = this.queryFactory.query(DmpQuery.class).authorize(this.authorize).ids(data.stream().map(DmpReferenceEntity::getDmpId).distinct().collect(Collectors.toList())); itemMap = this.builderFactory.builder(DmpBuilder.class).authorize(this.authorize).asForeignKey(q, clone, Dmp::getId); } if (!fields.hasField(Dmp._id)) { diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/SupportiveMaterialBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/SupportiveMaterialBuilder.java new file mode 100644 index 000000000..c465cd702 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/SupportiveMaterialBuilder.java @@ -0,0 +1,74 @@ +package eu.eudat.model.builder; + +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.DmpReferenceEntity; +import eu.eudat.data.SupportiveMaterialEntity; +import eu.eudat.model.Dmp; +import eu.eudat.model.DmpReference; +import eu.eudat.model.Reference; +import eu.eudat.model.SupportiveMaterial; +import eu.eudat.query.DmpQuery; +import eu.eudat.query.ReferenceQuery; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.fieldset.BaseFieldSet; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.DataLogEntry; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class SupportiveMaterialBuilder extends BaseBuilder{ + + private final BuilderFactory builderFactory; + private final QueryFactory queryFactory; + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + @Autowired + public SupportiveMaterialBuilder( + ConventionService conventionService, + BuilderFactory builderFactory, QueryFactory queryFactory) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(SupportiveMaterialBuilder.class))); + this.builderFactory = builderFactory; + this.queryFactory = queryFactory; + } + + public SupportiveMaterialBuilder authorize(EnumSet values) { + this.authorize = values; + return this; + } + + @Override + public List build(FieldSet fields, List data) throws MyApplicationException { + this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0)); + this.logger.trace(new DataLogEntry("requested fields", fields)); + if (fields == null || data == null || fields.isEmpty()) + return new ArrayList<>(); + + List models = new ArrayList<>(); + for (SupportiveMaterialEntity d : data) { + SupportiveMaterial m = new SupportiveMaterial(); + if (fields.hasField(this.asIndexer(SupportiveMaterial._id))) m.setId(d.getId()); + if (fields.hasField(this.asIndexer(SupportiveMaterial._type))) m.setType(d.getType()); + if (fields.hasField(this.asIndexer(SupportiveMaterial._languageCode))) m.setLanguageCode(d.getLanguageCode()); + if (fields.hasField(this.asIndexer(SupportiveMaterial._payload))) m.setPayload(d.getPayload()); + if (fields.hasField(this.asIndexer(SupportiveMaterial._createdAt))) m.setCreatedAt(d.getCreatedAt()); + if (fields.hasField(this.asIndexer(SupportiveMaterial._updatedAt))) m.setUpdatedAt(d.getUpdatedAt()); + if (fields.hasField(this.asIndexer(SupportiveMaterial._isActive))) m.setIsActive(d.getIsActive()); + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/DmpDescriptionTemplateCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/DmpDescriptionTemplateCensor.java new file mode 100644 index 000000000..aed5dd047 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/DmpDescriptionTemplateCensor.java @@ -0,0 +1,48 @@ +package eu.eudat.model.censorship; + +import eu.eudat.authorization.Permission; +import eu.eudat.convention.ConventionService; +import eu.eudat.model.DmpReference; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.censor.CensorFactory; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.DataLogEntry; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DmpDescriptionTemplateCensor extends BaseCensor{ + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpDescriptionTemplateCensor.class)); + + protected final AuthorizationService authService; + + protected final CensorFactory censorFactory; + + public DmpDescriptionTemplateCensor(ConventionService conventionService, + AuthorizationService authService, + CensorFactory censorFactory) { + super(conventionService); + this.authService = authService; + this.censorFactory = censorFactory; + } + + public void censor(FieldSet fields, UUID userId) { + logger.debug(new DataLogEntry("censoring fields", fields)); + if (fields == null || fields.isEmpty()) + return; + + this.authService.authorizeForce(Permission.BrowseDmpReference); + FieldSet dmpFields = fields.extractPrefixed(this.asIndexerPrefix(DmpReference._dmp)); + this.censorFactory.censor(DmpCensor.class).censor(dmpFields, userId); + FieldSet referenceFields = fields.extractPrefixed(this.asIndexerPrefix(DmpReference._reference)); + this.censorFactory.censor(ReferenceCensor.class).censor(referenceFields, userId); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/DmpReferenceCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/DmpReferenceCensor.java index 1ea827b13..574cd6c0d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/DmpReferenceCensor.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/DmpReferenceCensor.java @@ -2,6 +2,7 @@ package eu.eudat.model.censorship; import eu.eudat.authorization.Permission; import eu.eudat.convention.ConventionService; +import eu.eudat.model.DmpDescriptionTemplate; import eu.eudat.model.DmpReference; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.censor.CensorFactory; @@ -37,11 +38,11 @@ public class DmpReferenceCensor extends BaseCensor { if (fields == null || fields.isEmpty()) return; - this.authService.authorizeForce(Permission.BrowseDmpReference); - FieldSet dmpFields = fields.extractPrefixed(this.asIndexerPrefix(DmpReference._dmp)); + this.authService.authorizeForce(Permission.BrowseDmpDescriptionTemplate); + FieldSet dmpFields = fields.extractPrefixed(this.asIndexerPrefix(DmpDescriptionTemplate._dmp)); this.censorFactory.censor(DmpCensor.class).censor(dmpFields, userId); - FieldSet referenceFields = fields.extractPrefixed(this.asIndexerPrefix(DmpReference._reference)); - this.censorFactory.censor(ReferenceCensor.class).censor(referenceFields, userId); + FieldSet templateFields = fields.extractPrefixed(this.asIndexerPrefix(DmpDescriptionTemplate._descriptionTemplate)); + this.censorFactory.censor(DescriptionTemplateCensor.class).censor(templateFields, userId); } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/SupportiveMaterialCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/SupportiveMaterialCensor.java new file mode 100644 index 000000000..59943a975 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/SupportiveMaterialCensor.java @@ -0,0 +1,44 @@ +package eu.eudat.model.censorship; + +import eu.eudat.authorization.Permission; +import eu.eudat.convention.ConventionService; +import eu.eudat.model.DmpBlueprint; +import eu.eudat.model.censorship.dmpblueprintdefinition.DefinitionCensor; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.censor.CensorFactory; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.DataLogEntry; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class SupportiveMaterialCensor extends BaseCensor { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(SupportiveMaterialCensor.class)); + + protected final AuthorizationService authService; + protected final CensorFactory censorFactory; + + public SupportiveMaterialCensor(ConventionService conventionService, + AuthorizationService authService, + CensorFactory censorFactory) { + super(conventionService); + this.authService = authService; + this.censorFactory = censorFactory; + } + + public void censor(FieldSet fields, UUID userId) { + logger.debug(new DataLogEntry("censoring fields", fields)); + if (fields == null || fields.isEmpty()) + return; + + this.authService.authorizeForce(Permission.BrowseSupportiveMaterial); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DmpDescriptionTemplateDeleter.java b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DmpDescriptionTemplateDeleter.java new file mode 100644 index 000000000..404f96ee3 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DmpDescriptionTemplateDeleter.java @@ -0,0 +1,78 @@ +package eu.eudat.model.deleter; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.DmpDescriptionTemplateEntity; +import eu.eudat.data.DmpReferenceEntity; +import eu.eudat.query.DmpDescriptionTemplateQuery; +import eu.eudat.query.DmpReferenceQuery; +import gr.cite.tools.data.deleter.Deleter; +import gr.cite.tools.data.deleter.DeleterFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import jakarta.persistence.EntityManager; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.management.InvalidApplicationException; +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DmpDescriptionTemplateDeleter implements Deleter { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpDescriptionTemplateDeleter.class)); + private final EntityManager entityManager; + + protected final QueryFactory queryFactory; + + protected final DeleterFactory deleterFactory; + + @Autowired + public DmpDescriptionTemplateDeleter( + EntityManager entityManager, + QueryFactory queryFactory, + DeleterFactory deleterFactory + ) { + this.entityManager = entityManager; + this.queryFactory = queryFactory; + this.deleterFactory = deleterFactory; + } + + public void deleteAndSaveByIds(List ids) throws InvalidApplicationException { + logger.debug(new MapLogEntry("collecting to delete").And("count", Optional.ofNullable(ids).map(List::size).orElse(0)).And("ids", ids)); + List data = this.queryFactory.query(DmpDescriptionTemplateQuery.class).ids(ids).collect(); + logger.trace("retrieved {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.deleteAndSave(data); + } + + public void deleteAndSave(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.delete(data); + logger.trace("saving changes"); + this.entityManager.flush(); + logger.trace("changes saved"); + } + + public void delete(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + if (data == null || data.isEmpty()) + return; + + for (DmpDescriptionTemplateEntity item : data) { + logger.trace("deleting item {}", item.getId()); + logger.trace("updating item"); + item.setUpdatedAt(Instant.now()); + item.setIsActive(IsActive.Inactive); + this.entityManager.merge(item); + logger.trace("updated item"); + } + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DmpReferenceDeleter.java b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DmpReferenceDeleter.java index 5953ed6e3..89e3c2b69 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DmpReferenceDeleter.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DmpReferenceDeleter.java @@ -1,5 +1,6 @@ package eu.eudat.model.deleter; +import eu.eudat.commons.enums.IsActive; import eu.eudat.data.DmpReferenceEntity; import eu.eudat.query.DmpReferenceQuery; import gr.cite.tools.data.deleter.Deleter; @@ -15,6 +16,7 @@ import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import javax.management.InvalidApplicationException; +import java.time.Instant; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -64,6 +66,8 @@ public class DmpReferenceDeleter implements Deleter { for (DmpReferenceEntity item : data) { logger.trace("deleting item {}", item.getId()); logger.trace("updating item"); + item.setUpdatedAt(Instant.now()); + item.setIsActive(IsActive.Inactive); this.entityManager.merge(item); logger.trace("updated item"); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/deleter/SupportiveMaterialDeleter.java b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/SupportiveMaterialDeleter.java new file mode 100644 index 000000000..f5a548e64 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/SupportiveMaterialDeleter.java @@ -0,0 +1,79 @@ +package eu.eudat.model.deleter; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.SupportiveMaterialEntity; +import eu.eudat.query.SupportiveMaterialQuery; +import gr.cite.tools.data.deleter.Deleter; +import gr.cite.tools.data.deleter.DeleterFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import jakarta.persistence.EntityManager; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.management.InvalidApplicationException; +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class SupportiveMaterialDeleter implements Deleter { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(SupportiveMaterialDeleter.class)); + + private final EntityManager entityManager; + + protected final QueryFactory queryFactory; + + protected final DeleterFactory deleterFactory; + + @Autowired + public SupportiveMaterialDeleter( + EntityManager entityManager, + QueryFactory queryFactory, + DeleterFactory deleterFactory + ) { + this.entityManager = entityManager; + this.queryFactory = queryFactory; + this.deleterFactory = deleterFactory; + } + + public void deleteAndSaveByIds(List ids) throws InvalidApplicationException { + logger.debug(new MapLogEntry("collecting to delete").And("count", Optional.ofNullable(ids).map(List::size).orElse(0)).And("ids", ids)); + List data = this.queryFactory.query(SupportiveMaterialQuery.class).ids(ids).collect(); + logger.trace("retrieved {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.deleteAndSave(data); + } + + public void deleteAndSave(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.delete(data); + logger.trace("saving changes"); + this.entityManager.flush(); + logger.trace("changes saved"); + } + + public void delete(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + if (data == null || data.isEmpty()) + return; + + Instant now = Instant.now(); + + for (SupportiveMaterialEntity item : data) { + logger.trace("deleting item {}", item.getId()); + item.setIsActive(IsActive.Inactive); + item.setUpdatedAt(now); + logger.trace("updating item"); + this.entityManager.merge(item); + logger.trace("updated item"); + } + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositCode.java b/dmp-backend/core/src/main/java/eu/eudat/model/doi/DepositCode.java similarity index 92% rename from dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositCode.java rename to dmp-backend/core/src/main/java/eu/eudat/model/doi/DepositCode.java index a567dc9da..f60742540 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositCode.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/doi/DepositCode.java @@ -1,4 +1,4 @@ -package eu.eudat.models.data.doi; +package eu.eudat.model.doi; public class DepositCode { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositRequest.java b/dmp-backend/core/src/main/java/eu/eudat/model/doi/DepositRequest.java similarity index 94% rename from dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositRequest.java rename to dmp-backend/core/src/main/java/eu/eudat/model/doi/DepositRequest.java index b6ee1f4a3..7502769b3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositRequest.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/doi/DepositRequest.java @@ -1,4 +1,4 @@ -package eu.eudat.models.data.doi; +package eu.eudat.model.doi; public class DepositRequest { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/Doi.java b/dmp-backend/core/src/main/java/eu/eudat/model/doi/Doi.java similarity index 72% rename from dmp-backend/web/src/main/java/eu/eudat/models/data/doi/Doi.java rename to dmp-backend/core/src/main/java/eu/eudat/model/doi/Doi.java index 58fc97398..878e857c1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/Doi.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/doi/Doi.java @@ -1,8 +1,7 @@ -package eu.eudat.models.data.doi; +package eu.eudat.model.doi; import eu.eudat.data.EntityDoiEntity; -import eu.eudat.models.DataModel; -import eu.eudat.models.data.dmp.DataManagementPlan; +import eu.eudat.model.Dmp; import java.util.Date; import java.util.UUID; @@ -13,7 +12,7 @@ public class Doi { private String doi; private Date createdAt; private Date updatedAt; - private DataManagementPlan dmp; + private Dmp dmp; public UUID getId() { return id; @@ -50,20 +49,21 @@ public class Doi { this.updatedAt = updatedAt; } - public DataManagementPlan getDmp() { + public Dmp getDmp() { return dmp; } - public void setDmp(DataManagementPlan dmp) { + public void setDmp(Dmp dmp) { this.dmp = dmp; } - public Doi fromDataModel(EntityDoiEntity entity) { - this.id = entity.getId(); - this.repositoryId = entity.getRepositoryId(); - this.doi = entity.getDoi(); - this.createdAt = Date.from(entity.getCreatedAt()); - this.updatedAt = Date.from(entity.getUpdatedAt()); - return this; + public static Doi fromDataModel(EntityDoiEntity entity) { + Doi doi1 = new Doi(); + doi1.id = entity.getId(); + doi1.repositoryId = entity.getRepositoryId(); + doi1.doi = entity.getDoi(); + doi1.createdAt = Date.from(entity.getCreatedAt()); + doi1.updatedAt = Date.from(entity.getUpdatedAt()); + return doi1; } public EntityDoiEntity toDataModel() throws Exception { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/RepositoryConfig.java b/dmp-backend/core/src/main/java/eu/eudat/model/doi/RepositoryConfig.java similarity index 70% rename from dmp-backend/web/src/main/java/eu/eudat/models/data/doi/RepositoryConfig.java rename to dmp-backend/core/src/main/java/eu/eudat/model/doi/RepositoryConfig.java index 1c45346a0..ec62f7f09 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/RepositoryConfig.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/doi/RepositoryConfig.java @@ -1,7 +1,9 @@ -package eu.eudat.models.data.doi; +package eu.eudat.model.doi; import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; +import java.util.List; + public class RepositoryConfig { private int depositType; @@ -61,14 +63,16 @@ public class RepositoryConfig { this.hasLogo = hasLogo; } - public RepositoryConfig toModel(RepositoryDepositConfiguration r){ - this.setDepositType(r.getDepositType()); - this.setRepositoryId(r.getRepositoryId()); - this.setRepositoryAuthorizationUrl(r.getRepositoryAuthorizationUrl()); - this.setRepositoryRecordUrl(r.getRepositoryRecordUrl()); - this.setRepositoryClientId(r.getRepositoryClientId()); - this.setRedirectUri(r.getRedirectUri()); - this.setHasLogo(r.isHasLogo()); - return this; + public static RepositoryConfig toModel(RepositoryDepositConfiguration r){ + RepositoryConfig repositoryConfig = new RepositoryConfig(); + repositoryConfig.setDepositType(r.getDepositType()); + repositoryConfig.setRepositoryId(r.getRepositoryId()); + repositoryConfig.setRepositoryAuthorizationUrl(r.getRepositoryAuthorizationUrl()); + repositoryConfig.setRepositoryRecordUrl(r.getRepositoryRecordUrl()); + repositoryConfig.setRepositoryClientId(r.getRepositoryClientId()); + repositoryConfig.setRedirectUri(r.getRedirectUri()); + repositoryConfig.setHasLogo(r.isHasLogo()); + return repositoryConfig; } } + diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/doi/RepositoryConfigs.java b/dmp-backend/core/src/main/java/eu/eudat/model/doi/RepositoryConfigs.java new file mode 100644 index 000000000..b414bcb0e --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/doi/RepositoryConfigs.java @@ -0,0 +1,22 @@ +package eu.eudat.model.doi; + +import java.util.List; + +public class RepositoryConfigs { + private List repositoryConfigs; + + public RepositoryConfigs() { + } + + public RepositoryConfigs(List repositoryConfigs) { + this.repositoryConfigs = repositoryConfigs; + } + + public List getRepositoryConfigs() { + return repositoryConfigs; + } + + public void setRepositoryConfigs(List repositoryConfigs) { + this.repositoryConfigs = repositoryConfigs; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/helpers/FileEnvelope.java b/dmp-backend/core/src/main/java/eu/eudat/model/file/FileEnvelope.java similarity index 89% rename from dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/helpers/FileEnvelope.java rename to dmp-backend/core/src/main/java/eu/eudat/model/file/FileEnvelope.java index 899b4a3b6..3b5b25e39 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/helpers/FileEnvelope.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/file/FileEnvelope.java @@ -1,4 +1,4 @@ -package eu.eudat.logic.utilities.documents.helpers; +package eu.eudat.model.file; import java.io.File; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java b/dmp-backend/core/src/main/java/eu/eudat/model/mapper/deposit/DMPToDepositMapper.java similarity index 99% rename from dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java rename to dmp-backend/core/src/main/java/eu/eudat/model/mapper/deposit/DMPToDepositMapper.java index 4a57784f6..88bfdfef3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/mapper/deposit/DMPToDepositMapper.java @@ -1,4 +1,4 @@ -package eu.eudat.logic.security.repositorydeposit.mapper; +package eu.eudat.model.mapper.deposit; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/mapper/deposit/DmpEntityDepositMapper.java b/dmp-backend/core/src/main/java/eu/eudat/model/mapper/deposit/DmpEntityDepositMapper.java new file mode 100644 index 000000000..e9d360f16 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/mapper/deposit/DmpEntityDepositMapper.java @@ -0,0 +1,161 @@ +package eu.eudat.model.mapper.deposit; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.types.xml.XmlBuilder; +import eu.eudat.data.DescriptionEntity; +import eu.eudat.data.DescriptionTemplateEntity; +import eu.eudat.data.DmpEntity; +import eu.eudat.data.old.UserDMP; +import eu.eudat.data.old.UserInfo; +import eu.eudat.depositinterface.models.*; +import jakarta.persistence.EntityManager; +import jakarta.persistence.criteria.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.xpath.*; +import java.io.File; +import java.util.*; +import java.util.stream.Collectors; + +@Component +public class DmpEntityDepositMapper { + private static final Logger logger = LoggerFactory.getLogger(DmpEntityDepositMapper.class); + + private final ObjectMapper mapper; + + private final EntityManager entityManager; + + public DmpEntityDepositMapper(EntityManager entityManager) { + this.entityManager = entityManager; + this.mapper = new ObjectMapper(); + } + + //TODO: WIP, missing some things like researchers, organizations etc. Must check Blueprint properties and check if those have some standard way to be identified + public DMPDepositModel toDeposit(DmpEntity dmpEntity, File zip, FileEnvelope pdf, FileEnvelope json, String previousDOI) { + DMPDepositModel model = new DMPDepositModel(); + List desciptions = this.getDescriptions(dmpEntity.getId()); + List users = getUsers(dmpEntity.getId()); + model.setId(dmpEntity.getId()); + model.setLabel(dmpEntity.getLabel()); + model.setDescription(dmpEntity.getDescription()); + model.setVersion(dmpEntity.getVersion()); + model.setPdfFile(pdf); + model.setRdaJsonFile(json); + model.setSupportingFilesZip(zip); + model.setDatasets(desciptions.stream().map(this::toDatasetDeposit).toList()); + model.setExtraProperties(dmpEntity.getProperties()); + model.setUsers(users.stream().map(this::toUserDeposit).collect(Collectors.toSet())); + model.setPreviousDOI(previousDOI); + + return model; + } + + private List getDescriptions(UUID dmpId) { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(DescriptionEntity.class); + Root root = query.from(DescriptionEntity.class); + query = query.where(builder.and(builder.equal(root.get("dmp"), dmpId), builder.equal(root.get("isActive"), IsActive.Active))); + return entityManager.createQuery(query).getResultList(); + + } + + private DatasetDepositModel toDatasetDeposit(DescriptionEntity entity) { + DatasetDepositModel model = new DatasetDepositModel(); + model.setLabel(entity.getLabel()); + model.setDescription(entity.getDescription()); + model.setProperties(entity.getProperties()); + DescriptionTemplateEntity descriptionTemplateEntity = getDescriptionTemplate(entity.getProfile()); + model.setProfileDefinition(descriptionTemplateEntity.getDefinition()); + model.setFields(fromDefinitionAndProperties(descriptionTemplateEntity.getDefinition(), entity.getProperties())); + return model; + } + + private DescriptionTemplateEntity getDescriptionTemplate(UUID descId) { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(DescriptionTemplateEntity.class); + Root root = query.from(DescriptionTemplateEntity.class); + query = query.where(builder.and(builder.equal(root.get("id"), descId), builder.equal(root.get("isActive"), IsActive.Active))); + return entityManager.createQuery(query).getSingleResult(); + } + + private List fromDefinitionAndProperties(String definition, String properties){ + List deposit = new ArrayList<>(); + try { + + Map datasetAnswers = mapper.readValue(properties, HashMap.class); + + Document document = XmlBuilder.fromXml(definition); + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xpath = xpathFactory.newXPath(); + XPathExpression expr = xpath.compile("//schematics"); + NodeList schematics = (NodeList) expr.evaluate(document, XPathConstants.NODESET); + for (int i = 0; i < schematics.getLength(); i++) { + Node schematicsNode = schematics.item(i); + NodeList schematicsList = schematicsNode.getChildNodes(); + DatasetFieldsDepositModel fieldDeposit = new DatasetFieldsDepositModel(); + List schematicsDeposit = new ArrayList<>(); + if(schematicsList != null){ + for(int j = 0; j < schematicsList.getLength(); j++){ + Node schematic = schematicsList.item(j); + if(schematic.getTextContent().matches(".*\\w+.*")) { + schematicsDeposit.add(schematic.getTextContent()); + } + } + } + fieldDeposit.setSchematics(schematicsDeposit); + String fieldId = schematicsNode.getParentNode().getAttributes().getNamedItem("id").getNodeValue(); + Object value = datasetAnswers.get(fieldId); + fieldDeposit.setValue(value); + Element field = (Element) schematicsNode.getParentNode(); + Element viewStyle = (Element) field.getElementsByTagName("viewStyle").item(0); + String renderStyle = viewStyle.getAttribute("renderstyle"); + fieldDeposit.setRenderStyleType(renderStyle); + Element data = (Element) field.getElementsByTagName("data").item(0); + String multipleSelection = data.getAttribute("multiList"); + String multipleAutoComplete = data.getAttribute("multiAutoComplete"); + if(!multipleSelection.isEmpty()){ + fieldDeposit.setMultiple(Boolean.parseBoolean(multipleSelection)); + } + else if(!multipleAutoComplete.isEmpty()){ + fieldDeposit.setMultiple(Boolean.parseBoolean(multipleAutoComplete)); + } + else{ + fieldDeposit.setMultiple(false); + } + deposit.add(fieldDeposit); + } + } + catch (XPathExpressionException | JsonProcessingException ex){ + logger.error(ex.getMessage(), ex); + return null; + } + return deposit; + } + + private List getUsers(UUID dmpId) { + CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery query = builder.createQuery(UserDMP.class); + Root root = query.from(UserDMP.class); + Join join = root.join("user").join("id"); + query = query.multiselect(root.get("user"), root.get("role")); + return entityManager.createQuery(query).getResultList(); + } + + private UserDMPDepositModel toUserDeposit(UserDMP user) { + UserDMPDepositModel userDMPDepositModel = new UserDMPDepositModel(); + userDMPDepositModel.setUser(new UserInfoDepositModel()); + userDMPDepositModel.getUser().setName(user.getUser().getName()); + userDMPDepositModel.getUser().setEmail(user.getUser().getEmail()); + userDMPDepositModel.setRole(user.getRole()); + + return userDMPDepositModel; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpPersist.java index d1b2f8b45..dca97a350 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpPersist.java @@ -4,7 +4,7 @@ import eu.eudat.commons.enums.DmpStatus; import eu.eudat.commons.validation.ValidId; import eu.eudat.model.persist.dmpproperties.DmpPropertiesPersist; -import java.time.Instant; +import java.util.List; import java.util.UUID; public class DmpPersist { @@ -22,6 +22,8 @@ public class DmpPersist { private String language; + private List references; + private String hash; public UUID getId() { @@ -72,6 +74,14 @@ public class DmpPersist { this.language = language; } + public List getReferences() { + return references; + } + + public void setReferences(List references) { + this.references = references; + } + public String getHash() { return hash; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpReferencePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpReferencePersist.java new file mode 100644 index 000000000..bdb0209bf --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpReferencePersist.java @@ -0,0 +1,58 @@ +package eu.eudat.model.persist; + +import eu.eudat.commons.validation.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.ValidId; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; + +import java.util.UUID; + +@FieldNotNullIfOtherSet(message = "{validation.hashempty}") +public class DmpReferencePersist { + + @ValidId(message = "{validation.invalidid}") + private UUID id; + + @NotNull(message = "{validation.empty}") + @NotEmpty(message = "{validation.empty}") + private ReferencePersist reference; + + @NotNull(message = "{validation.empty}") + @NotEmpty(message = "{validation.empty}") + private String data; + + private String hash; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public ReferencePersist getReference() { + return reference; + } + + public void setReference(ReferencePersist reference) { + this.reference = reference; + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferencePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferencePersist.java index 29250acd6..ea0073ad8 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferencePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferencePersist.java @@ -46,6 +46,8 @@ public class ReferencePersist { @ValidEnum(message = "{validation.empty}") private ReferenceSourceType sourceType; + private String hash; + //private UserInfoPersist createdBy; ToDo @@ -120,4 +122,12 @@ public class ReferencePersist { public void setSourceType(ReferenceSourceType sourceType) { this.sourceType = sourceType; } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/SupportiveMaterialPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/SupportiveMaterialPersist.java index cd4d6b948..8c14508bc 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/SupportiveMaterialPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/SupportiveMaterialPersist.java @@ -2,28 +2,36 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.SupportiveMaterialFieldType; import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.ValidId; +import eu.eudat.data.DmpBlueprintEntity; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; -public class SupportiveMaterialPersist { +import java.util.UUID; - @NotNull(message = "{validation.empty}") - @NotEmpty(message = "{validation.empty}") - private String name; +public class SupportiveMaterialPersist { + @ValidId(message = "{validation.invalidid}") + private UUID id; @ValidEnum(message = "{validation.empty}") private SupportiveMaterialFieldType type; @NotNull(message = "{validation.empty}") @NotEmpty(message = "{validation.empty}") - private String html; + @Size(max = 20, message = "{validation.largerthanmax}") + private String languageCode; - public String getName() { - return name; + @NotNull(message = "{validation.empty}") + @NotEmpty(message = "{validation.empty}") + private String payload; + + public UUID getId() { + return id; } - public void setName(String name) { - this.name = name; + public void setId(UUID id) { + this.id = id; } public SupportiveMaterialFieldType getType() { @@ -34,11 +42,19 @@ public class SupportiveMaterialPersist { this.type = type; } - public String getHtml() { - return html; + public String getLanguageCode() { + return languageCode; } - public void setHtml(String html) { - this.html = html; + public void setLanguageCode(String languageCode) { + this.languageCode = languageCode; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpBlueprintValue.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpBlueprintValue.java index f255fc7cd..e3302e132 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpBlueprintValue.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpBlueprintValue.java @@ -21,4 +21,5 @@ public class DmpBlueprintValue { public void setFieldValue(String fieldValue) { this.fieldValue = fieldValue; } + } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpBlueprintValuePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpBlueprintValuePersist.java new file mode 100644 index 000000000..22256f6cb --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpBlueprintValuePersist.java @@ -0,0 +1,35 @@ +package eu.eudat.model.persist.dmpproperties; + +public class DmpBlueprintValuePersist { + + private String fieldId; + + private String fieldName; + + private String fieldValue; + + public String getFieldId() { + return fieldId; + } + + public void setFieldId(String fieldId) { + this.fieldId = fieldId; + } + + public String getFieldName() { + return fieldName; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public String getFieldValue() { + return fieldValue; + } + + public void setFieldValue(String fieldValue) { + this.fieldValue = fieldValue; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpContact.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpContact.java index c60fe0c08..99519ee5b 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpContact.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpContact.java @@ -41,4 +41,5 @@ public class DmpContact { public void setEmail(String email) { this.email = email; } + } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpContactPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpContactPersist.java new file mode 100644 index 000000000..b7309b775 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpContactPersist.java @@ -0,0 +1,45 @@ +package eu.eudat.model.persist.dmpproperties; + +public class DmpContactPersist { + + String userId; + + String firstName; + + String lastName; + + String email; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpPropertiesPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpPropertiesPersist.java index 849af6404..aeb38f7dc 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpPropertiesPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpproperties/DmpPropertiesPersist.java @@ -4,23 +4,23 @@ import java.util.List; public class DmpPropertiesPersist { - private List dmpBlueprintValues; + private List dmpBlueprintValues; - private List contacts; + private List contacts; - public List getDmpBlueprintValues() { + public List getDmpBlueprintValues() { return dmpBlueprintValues; } - public void setDmpBlueprintValues(List dmpBlueprintValues) { + public void setDmpBlueprintValues(List dmpBlueprintValues) { this.dmpBlueprintValues = dmpBlueprintValues; } - public List getContacts() { + public List getContacts() { return contacts; } - public void setContacts(List contacts) { + public void setContacts(List contacts) { this.contacts = contacts; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DmpDescriptionTemplateQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DmpDescriptionTemplateQuery.java new file mode 100644 index 000000000..fef4167e0 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DmpDescriptionTemplateQuery.java @@ -0,0 +1,160 @@ +package eu.eudat.query; + +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.scope.user.UserScope; +import eu.eudat.data.DmpDescriptionTemplateEntity; +import eu.eudat.data.DmpReferenceEntity; +import eu.eudat.model.DmpDescriptionTemplate; +import eu.eudat.model.DmpReference; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.data.query.QueryBase; +import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.Tuple; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.Predicate; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.time.Instant; +import java.util.*; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DmpDescriptionTemplateQuery extends QueryBase { + + private Collection ids; + + private Collection dmpIds; + + private Collection descriptionTemplateIds; + + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + + public DmpDescriptionTemplateQuery ids(UUID value) { + this.ids = List.of(value); + return this; + } + + public DmpDescriptionTemplateQuery ids(UUID... value) { + this.ids = Arrays.asList(value); + return this; + } + + public DmpDescriptionTemplateQuery ids(Collection values) { + this.ids = values; + return this; + } + + public DmpDescriptionTemplateQuery dmpIds(UUID value) { + this.dmpIds = List.of(value); + return this; + } + + public DmpDescriptionTemplateQuery dmpIds(UUID... value) { + this.dmpIds = Arrays.asList(value); + return this; + } + + public DmpDescriptionTemplateQuery dmpIds(Collection values) { + this.dmpIds = values; + return this; + } + + public DmpDescriptionTemplateQuery descriptionTemplateIds(UUID value) { + this.descriptionTemplateIds = List.of(value); + return this; + } + + public DmpDescriptionTemplateQuery descriptionTemplateIds(UUID... value) { + this.descriptionTemplateIds = Arrays.asList(value); + return this; + } + + public DmpDescriptionTemplateQuery descriptionTemplateIds(Collection values) { + this.descriptionTemplateIds = values; + return this; + } + + public DmpDescriptionTemplateQuery authorize(EnumSet values) { + this.authorize = values; + return this; + } + + private final UserScope userScope; + + private final AuthorizationService authService; + + public DmpDescriptionTemplateQuery( + UserScope userScope, + AuthorizationService authService + ) { + this.userScope = userScope; + this.authService = authService; + } + + @Override + protected Class entityClass() { + return DmpDescriptionTemplateEntity.class; + } + + @Override + protected Boolean isFalseQuery() { + return this.isEmpty(this.ids) || this.isEmpty(this.dmpIds) || this.isEmpty(this.descriptionTemplateIds); + } + + @Override + protected Predicate applyFilters(QueryContext queryContext) { + List predicates = new ArrayList<>(); + if (this.ids != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpDescriptionTemplateEntity._id)); + for (UUID item : this.ids) + inClause.value(item); + predicates.add(inClause); + } + if (this.dmpIds != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpDescriptionTemplateEntity._dmp)); + for (UUID item : this.dmpIds) + inClause.value(item); + predicates.add(inClause); + } + if (this.descriptionTemplateIds != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpDescriptionTemplateEntity._descriptionTemplate)); + for (UUID item : this.descriptionTemplateIds) + inClause.value(item); + predicates.add(inClause); + } + if (!predicates.isEmpty()) { + Predicate[] predicatesArray = predicates.toArray(new Predicate[0]); + return queryContext.CriteriaBuilder.and(predicatesArray); + } else { + return null; + } + } + + @Override + protected DmpDescriptionTemplateEntity convert(Tuple tuple, Set columns) { + DmpDescriptionTemplateEntity item = new DmpDescriptionTemplateEntity(); + item.setId(QueryBase.convertSafe(tuple, columns, DmpDescriptionTemplateEntity._id, UUID.class)); + item.setDmp(QueryBase.convertSafe(tuple, columns, DmpDescriptionTemplateEntity._dmp, UUID.class)); + item.setDescriptionTemplate(QueryBase.convertSafe(tuple, columns, DmpDescriptionTemplateEntity._descriptionTemplate, UUID.class)); + item.setSectionId(QueryBase.convertSafe(tuple, columns, DmpDescriptionTemplateEntity._sectionId, UUID.class)); + item.setCreatedAt(QueryBase.convertSafe(tuple, columns, DmpDescriptionTemplateEntity._createdAt, Instant.class)); + item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, DmpDescriptionTemplateEntity._updatedAt, Instant.class)); + return item; + } + + @Override + protected String fieldNameOf(FieldResolver item) { + if (item.match(DmpDescriptionTemplate._id)) return DmpDescriptionTemplateEntity._id; + else if (item.prefix(DmpDescriptionTemplate._dmp)) return DmpDescriptionTemplateEntity._dmp; + else if (item.prefix(DmpDescriptionTemplate._descriptionTemplate)) return DmpDescriptionTemplateEntity._descriptionTemplate; + else if (item.match(DmpDescriptionTemplate._sectionId)) return DmpDescriptionTemplateEntity._sectionId; + else if (item.match(DmpDescriptionTemplate._createdAt)) return DmpDescriptionTemplateEntity._createdAt; + else if (item.match(DmpDescriptionTemplate._updatedAt)) return DmpDescriptionTemplateEntity._updatedAt; + else return null; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java index 3d0a80367..f8eac72e8 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java @@ -224,6 +224,7 @@ public class DmpQuery extends QueryBase { else if (item.match(Dmp._isActive)) return DmpEntity._isActive; else if (item.match(Dmp._finalizedAt)) return DmpEntity._finalizedAt; else if (item.match(Dmp._accessType)) return DmpEntity._accessType; + else if (item.match(Dmp._creator)) return DmpEntity._creator; else if (item.match(Dmp._blueprint)) return DmpEntity._blueprint; else if (item.match(Dmp._language)) return DmpEntity._language; else if (item.match(Dmp._publicAfter)) return DmpEntity._publicAfter; @@ -245,6 +246,7 @@ public class DmpQuery extends QueryBase { item.setIsActive(QueryBase.convertSafe(tuple, columns, DmpEntity._isActive, IsActive.class)); item.setFinalizedAt(QueryBase.convertSafe(tuple, columns, DmpEntity._finalizedAt, Instant.class)); item.setAccessType(QueryBase.convertSafe(tuple, columns, DmpEntity._accessType, DmpAccessType.class)); + item.setCreator(QueryBase.convertSafe(tuple, columns, DmpEntity._creator, UUID.class)); item.setBlueprint(QueryBase.convertSafe(tuple, columns, DmpEntity._blueprint, UUID.class)); item.setLanguage(QueryBase.convertSafe(tuple, columns, DmpEntity._language, String.class)); item.setPublicAfter(QueryBase.convertSafe(tuple, columns, DmpEntity._publicAfter, Instant.class)); diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DmpReferenceQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DmpReferenceQuery.java index d4ef92663..72c837fe3 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DmpReferenceQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DmpReferenceQuery.java @@ -114,7 +114,7 @@ public class DmpReferenceQuery extends QueryBase { } if (this.dmpIds != null) { CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpReferenceEntity._dmpId)); - for (UUID item : this.ids) + for (UUID item : this.dmpIds) inClause.value(item); predicates.add(inClause); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/ReferenceQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/ReferenceQuery.java index c2503d74a..20b86852c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/ReferenceQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/ReferenceQuery.java @@ -6,6 +6,7 @@ import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.ReferenceSourceType; import eu.eudat.commons.scope.user.UserScope; import eu.eudat.data.ReferenceEntity; +import eu.eudat.model.Reference; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; @@ -213,18 +214,18 @@ public class ReferenceQuery extends QueryBase { @Override protected String fieldNameOf(FieldResolver item) { if (item.match(ReferenceEntity._id)) return ReferenceEntity._id; - else if (item.match(ReferenceEntity._label)) return ReferenceEntity._label; - else if (item.match(ReferenceEntity._description)) return ReferenceEntity._description; - else if (item.match(ReferenceEntity._createdAt)) return ReferenceEntity._createdAt; - else if (item.match(ReferenceEntity._updatedAt)) return ReferenceEntity._updatedAt; - else if (item.match(ReferenceEntity._isActive)) return ReferenceEntity._isActive; - else if (item.match(ReferenceEntity._definition)) return ReferenceEntity._definition; - else if (item.match(ReferenceEntity._abbreviation)) return ReferenceEntity._abbreviation; - else if (item.match(ReferenceEntity._reference)) return ReferenceEntity._reference; - else if (item.match(ReferenceEntity._source)) return ReferenceEntity._source; - else if (item.match(ReferenceEntity._sourceType)) return ReferenceEntity._sourceType; - else if (item.match(ReferenceEntity._type)) return ReferenceEntity._type; - //else if (item.prefix(ReferenceEntity._createdBy)) return ReferenceEntity._createdBy; + else if (item.match(Reference._label)) return ReferenceEntity._label; + else if (item.match(Reference._description)) return ReferenceEntity._description; + else if (item.match(Reference._createdAt)) return ReferenceEntity._createdAt; + else if (item.match(Reference._updatedAt)) return ReferenceEntity._updatedAt; + else if (item.match(Reference._isActive)) return ReferenceEntity._isActive; + else if (item.match(Reference._definition)) return ReferenceEntity._definition; + else if (item.match(Reference._abbreviation)) return ReferenceEntity._abbreviation; + else if (item.match(Reference._reference)) return ReferenceEntity._reference; + else if (item.match(Reference._source)) return ReferenceEntity._source; + else if (item.match(Reference._sourceType)) return ReferenceEntity._sourceType; + else if (item.match(Reference._type)) return ReferenceEntity._type; + //else if (item.prefix(Reference._createdBy)) return ReferenceEntity._createdBy; else return null; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/SupportiveMaterialQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/SupportiveMaterialQuery.java new file mode 100644 index 000000000..5601eb2dc --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/query/SupportiveMaterialQuery.java @@ -0,0 +1,220 @@ +package eu.eudat.query; + +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.enums.SupportiveMaterialFieldType; +import eu.eudat.commons.scope.user.UserScope; +import eu.eudat.data.SupportiveMaterialEntity; +import eu.eudat.model.SupportiveMaterial; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.data.query.QueryBase; +import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.Tuple; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.Predicate; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.time.Instant; +import java.util.*; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class SupportiveMaterialQuery extends QueryBase { + + private String like; + + private Collection ids; + + private Collection isActives; + + private Collection types; + + private Collection languageCodes; + + private Collection excludedIds; + + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + public SupportiveMaterialQuery like(String value) { + this.like = value; + return this; + } + + public SupportiveMaterialQuery ids(UUID value) { + this.ids = List.of(value); + return this; + } + + public SupportiveMaterialQuery ids(UUID... value) { + this.ids = Arrays.asList(value); + return this; + } + + public SupportiveMaterialQuery ids(Collection values) { + this.ids = values; + return this; + } + + public SupportiveMaterialQuery isActive(IsActive value) { + this.isActives = List.of(value); + return this; + } + + public SupportiveMaterialQuery isActive(IsActive... value) { + this.isActives = Arrays.asList(value); + return this; + } + + public SupportiveMaterialQuery isActive(Collection values) { + this.isActives = values; + return this; + } + + public SupportiveMaterialQuery types(SupportiveMaterialFieldType value) { + this.types = List.of(value); + return this; + } + + public SupportiveMaterialQuery types(SupportiveMaterialFieldType... value) { + this.types = Arrays.asList(value); + return this; + } + + public SupportiveMaterialQuery types(Collection values) { + this.types = values; + return this; + } + + public SupportiveMaterialQuery languageCodes(String value) { + this.languageCodes = List.of(value); + return this; + } + + public SupportiveMaterialQuery languageCodes(String... value) { + this.languageCodes = Arrays.asList(value); + return this; + } + + public SupportiveMaterialQuery languageCodes(Collection values) { + this.languageCodes = values; + return this; + } + + public SupportiveMaterialQuery excludedIds(Collection values) { + this.excludedIds = values; + return this; + } + + public SupportiveMaterialQuery excludedIds(UUID value) { + this.excludedIds = List.of(value); + return this; + } + + public SupportiveMaterialQuery excludedIds(UUID... value) { + this.excludedIds = Arrays.asList(value); + return this; + } + + public SupportiveMaterialQuery authorize(EnumSet values) { + this.authorize = values; + return this; + } + + private final UserScope userScope; + + private final AuthorizationService authService; + + public SupportiveMaterialQuery( + UserScope userScope, + AuthorizationService authService + ) { + this.userScope = userScope; + this.authService = authService; + } + + @Override + protected Class entityClass() { + return SupportiveMaterialEntity.class; + } + + @Override + protected Boolean isFalseQuery() { + return this.isEmpty(this.ids) || this.isEmpty(this.isActives) || this.isEmpty(this.excludedIds) || this.isEmpty(this.types) || this.isEmpty(this.languageCodes); + } + + @Override + protected Predicate applyFilters(QueryContext queryContext) { + List predicates = new ArrayList<>(); + if (this.ids != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(SupportiveMaterialEntity._id)); + for (UUID item : this.ids) + inClause.value(item); + predicates.add(inClause); + } + if (this.like != null && !this.like.isEmpty()) { + predicates.add(queryContext.CriteriaBuilder.or(queryContext.CriteriaBuilder.like(queryContext.Root.get(SupportiveMaterialEntity._languageCode), this.like), + queryContext.CriteriaBuilder.like(queryContext.Root.get(SupportiveMaterialEntity._payload), this.like) + )); + } + if (this.isActives != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(SupportiveMaterialEntity._isActive)); + for (IsActive item : this.isActives) + inClause.value(item); + predicates.add(inClause); + } + + if (this.types != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(SupportiveMaterialEntity._type)); + for (SupportiveMaterialFieldType item : this.types) + inClause.value(item); + predicates.add(inClause); + } + if (this.languageCodes != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(SupportiveMaterialEntity._languageCode)); + for (String item : this.languageCodes) + inClause.value(item); + predicates.add(inClause); + } + if (this.excludedIds != null) { + CriteriaBuilder.In notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(SupportiveMaterialEntity._id)); + for (UUID item : this.excludedIds) + notInClause.value(item); + predicates.add(notInClause.not()); + } + if (!predicates.isEmpty()) { + Predicate[] predicatesArray = predicates.toArray(new Predicate[0]); + return queryContext.CriteriaBuilder.and(predicatesArray); + } else { + return null; + } + } + + @Override + protected SupportiveMaterialEntity convert(Tuple tuple, Set columns) { + SupportiveMaterialEntity item = new SupportiveMaterialEntity(); + item.setId(QueryBase.convertSafe(tuple, columns, SupportiveMaterialEntity._id, UUID.class)); + item.setType(QueryBase.convertSafe(tuple, columns, SupportiveMaterialEntity._type, SupportiveMaterialFieldType.class)); + item.setLanguageCode(QueryBase.convertSafe(tuple, columns, SupportiveMaterialEntity._languageCode, String.class)); + item.setPayload(QueryBase.convertSafe(tuple, columns, SupportiveMaterialEntity._payload, String.class)); + item.setCreatedAt(QueryBase.convertSafe(tuple, columns, SupportiveMaterialEntity._createdAt, Instant.class)); + item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, SupportiveMaterialEntity._updatedAt, Instant.class)); + item.setIsActive(QueryBase.convertSafe(tuple, columns, SupportiveMaterialEntity._isActive, IsActive.class)); + return item; + } + + @Override + protected String fieldNameOf(FieldResolver item) { + if (item.match(SupportiveMaterial._id)) return SupportiveMaterialEntity._id; + else if (item.match(SupportiveMaterial._type)) return SupportiveMaterialEntity._type; + else if (item.match(SupportiveMaterial._languageCode)) return SupportiveMaterialEntity._languageCode; + else if (item.match(SupportiveMaterial._payload)) return SupportiveMaterialEntity._payload; + else if (item.match(SupportiveMaterial._createdAt)) return SupportiveMaterialEntity._createdAt; + else if (item.match(SupportiveMaterial._updatedAt)) return SupportiveMaterialEntity._updatedAt; + else if (item.match(SupportiveMaterial._isActive)) return SupportiveMaterialEntity._isActive; + else return null; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/lookup/SupportiveMaterialLookup.java b/dmp-backend/core/src/main/java/eu/eudat/query/lookup/SupportiveMaterialLookup.java new file mode 100644 index 000000000..8e0160dc5 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/query/lookup/SupportiveMaterialLookup.java @@ -0,0 +1,89 @@ +package eu.eudat.query.lookup; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.enums.SupportiveMaterialFieldType; +import eu.eudat.query.SupportiveMaterialQuery; +import gr.cite.tools.data.query.Lookup; +import gr.cite.tools.data.query.QueryFactory; + +import java.util.Collection; +import java.util.List; +import java.util.UUID; + +public class SupportiveMaterialLookup extends Lookup { + + private String like; + + private List isActive; + + private Collection types; + + private List languageCodes; + + private List ids; + + private List excludedIds; + + public String getLike() { + return like; + } + + public void setLike(String like) { + this.like = like; + } + + public List getIsActive() { + return isActive; + } + + public void setIsActive(List isActive) { + this.isActive = isActive; + } + + public List getIds() { + return ids; + } + + public void setIds(List ids) { + this.ids = ids; + } + + public List getExcludedIds() { + return excludedIds; + } + + public void setExcludedIds(List excludeIds) { + this.excludedIds = excludeIds; + } + + public Collection getTypes() { + return types; + } + + public void setTypes(Collection types) { + this.types = types; + } + + public List getLanguageCodes() { + return languageCodes; + } + + public void setLanguageCodes(List languageCodes) { + this.languageCodes = languageCodes; + } + + public SupportiveMaterialQuery enrich(QueryFactory queryFactory) { + SupportiveMaterialQuery query = queryFactory.query(SupportiveMaterialQuery.class); + if (this.like != null) query.like(this.like); + if (this.isActive != null) query.isActive(this.isActive); + if (this.types != null) query.types(this.types); + if (this.languageCodes != null) query.languageCodes(this.languageCodes); + if (this.ids != null) query.ids(this.ids); + if (this.excludedIds != null) query.excludedIds(this.excludedIds); + + this.enrichCommon(query); + + return query; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/repository/DepositRepository.java b/dmp-backend/core/src/main/java/eu/eudat/repository/DepositRepository.java index c0dd332b3..9bfb21bca 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/repository/DepositRepository.java +++ b/dmp-backend/core/src/main/java/eu/eudat/repository/DepositRepository.java @@ -6,14 +6,17 @@ import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; import org.springframework.core.ParameterizedTypeReference; import org.springframework.web.reactive.function.client.WebClient; +import java.util.ArrayList; import java.util.List; public class DepositRepository implements RepositoryDeposit { private final WebClient depositClient; + private final List configurationIds; public DepositRepository(WebClient depositClient) { this.depositClient = depositClient; + this.configurationIds = new ArrayList<>(); } @@ -36,4 +39,8 @@ public class DepositRepository implements RepositoryDeposit { public String getLogo(String repositoryId) { return depositClient.get().uri("/logo/" + repositoryId).exchangeToMono(mono -> mono.bodyToMono(String.class)).block(); } + + public List getConfigurationIds() { + return configurationIds; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java new file mode 100644 index 000000000..b7617a1ef --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java @@ -0,0 +1,207 @@ +package eu.eudat.service.deposit; + +import eu.eudat.authorization.Permission; +import eu.eudat.cache.deposit.RepositoryDepositConfigurationCache; +import eu.eudat.commons.enums.EntityType; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.configurations.deposit.DepositProperties; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.DmpEntity; +import eu.eudat.data.EntityDoiEntity; +import eu.eudat.data.old.DMP; +import eu.eudat.depositinterface.models.DMPDepositModel; +import eu.eudat.depositinterface.models.FileEnvelope; +import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; +import eu.eudat.model.doi.DepositRequest; +import eu.eudat.model.doi.Doi; +import eu.eudat.model.doi.RepositoryConfig; +import eu.eudat.model.doi.RepositoryConfigs; +import eu.eudat.model.mapper.deposit.DmpEntityDepositMapper; +import eu.eudat.repository.DepositRepository; +import eu.eudat.utilities.pdf.PDFUtils; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.commons.web.oidc.apikey.ApiKeyCacheService; +import gr.cite.commons.web.oidc.apikey.webflux.ApiKeyExchangeFilterFunction; +import gr.cite.commons.web.oidc.apikey.webflux.ApiKeyWebfluxModel; +import jakarta.persistence.EntityManager; +import jakarta.persistence.NoResultException; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.CriteriaQuery; +import jakarta.persistence.criteria.Join; +import jakarta.persistence.criteria.Root; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; +import org.springframework.util.ResourceUtils; +import org.springframework.web.reactive.function.client.WebClient; + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@Service +public class RepositoryDepositService { + private static final Logger logger = LoggerFactory.getLogger(RepositoryDepositService.class); + + private final DepositProperties depositProperties; + private final List clients; + private final ApiKeyCacheService apiKeyCacheService; + private final RepositoryDepositConfigurationCache repositoryDepositConfigurationCache; + private final EntityManager entityManager; + private final AuthorizationService authorizationService; + private final ConventionService conventionService; + private final Environment environment; + private final DmpEntityDepositMapper depositMapper; + + @Autowired + public RepositoryDepositService(DepositProperties depositProperties, ApiKeyCacheService apiKeyCacheService, RepositoryDepositConfigurationCache repositoryDepositConfigurationCache, WebClient.Builder builder, EntityManager entityManager, AuthorizationService authorizationService, ConventionService conventionService, Environment environment, DmpEntityDepositMapper depositMapper) { + this.depositProperties = depositProperties; + this.apiKeyCacheService = apiKeyCacheService; + this.repositoryDepositConfigurationCache = repositoryDepositConfigurationCache; + this.clients = depositRepositories(builder); + this.entityManager = entityManager; + this.authorizationService = authorizationService; + this.conventionService = conventionService; + this.environment = environment; + this.depositMapper = depositMapper; + //GK: I don't like this but that way you can both cache the available configurations and set Configuration Ids for each client + getAvailableConfigurations(); + } + + + public List getAvailableConfigurations() { + RepositoryConfigs configs = repositoryDepositConfigurationCache.lookup("base"); + if (configs == null) { + List configurations = new ArrayList<>(); + + clients.forEach((client) -> { + List repositoryConfigs = client.getConfiguration(); + if (repositoryConfigs != null && !repositoryConfigs.isEmpty()) { + client.getConfigurationIds().addAll(repositoryConfigs.stream().map(RepositoryDepositConfiguration::getRepositoryId).toList()); + configurations.addAll(repositoryConfigs.stream().map(RepositoryConfig::toModel).toList()); + } + }); + + configs = new RepositoryConfigs(configurations); + this.repositoryDepositConfigurationCache.put("base", configs); + } + + return configs.getRepositoryConfigs(); + } + + public Doi deposit(DepositRequest dmpDepositModel) { + this.authorizationService.authorize(Permission.EditDmp); + //GK: Why it is in that service, and why it's not static? + this.conventionService.isValidGuid(UUID.fromString(dmpDepositModel.getDmpId())); + //GK: First get the right client + DepositRepository repository = clients.stream().filter(client -> client.getConfigurationIds().contains(dmpDepositModel.getRepositoryId())).findFirst().orElseThrow(); + //GK: Second get the Target Data Management Plan + DmpEntity dmpEntity = this.entityManager.find(DmpEntity.class, UUID.fromString(dmpDepositModel.getDmpId())); + + //GK: Third get the DOI from the previous Data Management Plan (if it exists) + String previousDOI = null; + if (dmpEntity.getVersion() > 1) { //TODO: Will it start from 1 or 0? + previousDOI = this.getPreviousDOI(dmpEntity.getGroupId(), dmpEntity.getId(), dmpDepositModel.getRepositoryId()); + } + + //GK: Forth make the required files to be uploaded with the deposit + //TODO: Properly create required files + FileEnvelope docEnvelope = new FileEnvelope(); + FileEnvelope pdfEnvelope = new FileEnvelope(); + FileEnvelope jsonEnvelope = new FileEnvelope(); + File zip = new File(environment.getProperty("temp.temp") + UUID.randomUUID() + ".zip"); + try { + File documentFile = ResourceUtils.getFile(this.environment.getProperty("coniguration.h2020template")); + docEnvelope.setFilename("test.docx"); + docEnvelope.setFile(documentFile); + File pdfFile = PDFUtils.convertToPDF(docEnvelope, environment); + pdfEnvelope.setFilename("test.pdf"); + pdfEnvelope.setFile(pdfFile); + File jsonFile = new File(this.environment.getProperty("temp.temp") + UUID.randomUUID() + ".json"); + jsonEnvelope.setFilename("test.json"); + jsonEnvelope.setFile(jsonFile); + + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + + //GK: Fifth Transform them to the DepositModel + DMPDepositModel depositModel = depositMapper.toDeposit(dmpEntity, zip, pdfEnvelope, jsonEnvelope, previousDOI); + + //GK: Sixth Perform the deposit + String doi = ""; + try { + doi = repository.deposit(dmpDepositModel.getRepositoryId(), depositModel, ""); + } catch (Exception e) { + logger.error(e.getMessage(), e); + } + //GK: Something has gone wrong return null + if (doi.isEmpty()) + return null; + //GK: doi is fine store it in database + EntityDoiEntity doiEntity = new EntityDoiEntity(); + doiEntity.setId(UUID.randomUUID()); + doiEntity.setDoi(doi); + doiEntity.setEntityType(EntityType.DMP); + DMP dmp = new DMP(); + dmp.setId(dmpEntity.getId()); + doiEntity.setEntityId(dmp); + doiEntity.setCreatedAt(Instant.now()); + doiEntity.setIsActive(IsActive.Active); + entityManager.persist(doiEntity); + + + return Doi.fromDataModel(doiEntity); + } + + private List depositRepositories(WebClient.Builder builder) { + List tclients = new ArrayList<>(); + for (DepositProperties.DepositSource source: depositProperties.getSources()) { + + String host = URI.create(source.getUrl()).getHost(); + ApiKeyWebfluxModel apiKeyWebfluxModel = new ApiKeyWebfluxModel(host + "_" + source.getClientId(), source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope()); + ApiKeyExchangeFilterFunction apiKeyExchangeFilterFunction = new ApiKeyExchangeFilterFunction(this.apiKeyCacheService, apiKeyWebfluxModel); + + tclients.add(new DepositRepository(builder.baseUrl(source.getUrl() + "/api/deposit").filters(exchangeFilterFunctions -> exchangeFilterFunctions.add(apiKeyExchangeFilterFunction)).build())); + } + return tclients; + } + + private String getPreviousDOI(UUID groupId, UUID currentId, String repoId) { + CriteriaBuilder builder = this.entityManager.getCriteriaBuilder(); + EntityDoiEntity doiEntity = null; + + //GK: Step one get the previous version of the Data management plan + CriteriaQuery query = builder.createQuery(DmpEntity.class); + Root root = query.from(DmpEntity.class); + query = query.select(root.get("id")); + query = query.where(builder.and(builder.equal(root.get("groupId"), groupId), builder.equal(root.get("isActive"), IsActive.Active))); + query = query.orderBy(builder.desc(root.get("version"))); + List dmpIds = this.entityManager.createQuery(query).getResultList().stream().map(DmpEntity::getId).toList(); + + //GK: Step two get it's doiEntity + CriteriaQuery doiQuery = builder.createQuery(EntityDoiEntity.class); + Root doiRoot = doiQuery.from(EntityDoiEntity.class); + doiQuery = doiQuery.multiselect(doiRoot.get("entityId").get("id"), doiRoot.get("doi")); + doiQuery = doiQuery.where(builder.and(doiRoot.get("entityId").get("id").in(dmpIds), builder.equal(doiRoot.get("isActive"), IsActive.Active), builder.equal(doiRoot.get("repositoryId"), repoId))); + List dois = this.entityManager.createQuery(doiQuery).getResultList(); + + for(UUID uuid: dmpIds) + { + if (uuid.equals(currentId)) + continue; + doiEntity = dois.stream() + .filter(entityDoiEntity -> entityDoiEntity.getEntityId().getId().equals(uuid)).findFirst().orElse(null); + if (doiEntity != null) + break; + } + return doiEntity != null ? doiEntity.getDoi() : null; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplatetype/DescriptionTemplateTypeServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplatetype/DescriptionTemplateTypeServiceImpl.java index 59c7f71b8..68d2e388c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplatetype/DescriptionTemplateTypeServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplatetype/DescriptionTemplateTypeServiceImpl.java @@ -112,7 +112,7 @@ public class DescriptionTemplateTypeServiceImpl implements DescriptionTemplateTy } public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException { - logger.debug("deleting dataset: {}", id); + logger.debug("deleting descriptionTemplateType: {}", id); this.authorizationService.authorizeForce(Permission.DeleteDescriptionTemplateType); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java index 04c5875ce..43301a64f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java @@ -19,7 +19,7 @@ import java.util.UUID; public interface DmpService { - Dmp persist(DmpPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException; + Dmp persist(DmpPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JsonProcessingException; void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException; diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java index 7de87d0e5..0774b1a89 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java @@ -4,20 +4,31 @@ import com.fasterxml.jackson.core.JsonProcessingException; import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.authorization.Permission; import eu.eudat.commons.JsonHandlingService; +import eu.eudat.commons.XmlHandlingService; import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.types.reference.DefinitionEntity; +import eu.eudat.commons.types.reference.FieldEntity; import eu.eudat.convention.ConventionService; -import eu.eudat.data.DescriptionTemplateEntity; import eu.eudat.data.DmpEntity; +import eu.eudat.data.DmpReferenceEntity; +import eu.eudat.data.ReferenceEntity; import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.event.DmpTouchedEvent; import eu.eudat.event.EventBroker; -import eu.eudat.model.DescriptionTemplate; import eu.eudat.model.Dmp; -import eu.eudat.model.builder.DescriptionTemplateBuilder; +import eu.eudat.model.Reference; import eu.eudat.model.builder.DmpBuilder; import eu.eudat.model.deleter.DmpDeleter; +import eu.eudat.model.deleter.DmpReferenceDeleter; +import eu.eudat.model.deleter.ReferenceDeleter; import eu.eudat.model.persist.DmpPersist; +import eu.eudat.model.persist.DmpReferencePersist; +import eu.eudat.model.persist.ReferencePersist; +import eu.eudat.model.persist.referencedefinition.DefinitionPersist; +import eu.eudat.model.persist.referencedefinition.FieldPersist; import eu.eudat.query.DmpQuery; +import eu.eudat.query.DmpReferenceQuery; +import eu.eudat.query.ReferenceQuery; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.deleter.DeleterFactory; @@ -33,6 +44,7 @@ import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.MapLogEntry; import jakarta.persistence.EntityManager; import jakarta.xml.bind.JAXBException; +import org.jetbrains.annotations.NotNull; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; @@ -43,8 +55,11 @@ import javax.management.InvalidApplicationException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import java.time.Instant; +import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; @Service public class DmpServiceImpl implements DmpService { @@ -67,6 +82,8 @@ public class DmpServiceImpl implements DmpService { private final MessageSource messageSource; + private final XmlHandlingService xmlHandlingService; + private final JsonHandlingService jsonHandlingService; private final EventBroker eventBroker; @@ -80,7 +97,7 @@ public class DmpServiceImpl implements DmpService { QueryFactory queryFactory, ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, - JsonHandlingService jsonHandlingService, + XmlHandlingService xmlHandlingService, JsonHandlingService jsonHandlingService, EventBroker eventBroker) { this.entityManager = entityManager; this.authorizationService = authorizationService; @@ -90,49 +107,23 @@ public class DmpServiceImpl implements DmpService { this.conventionService = conventionService; this.errors = errors; this.messageSource = messageSource; + this.xmlHandlingService = xmlHandlingService; this.jsonHandlingService = jsonHandlingService; this.eventBroker = eventBroker; } - public Dmp persist(DmpPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException { + public Dmp persist(DmpPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JsonProcessingException { logger.debug(new MapLogEntry("persisting data dmp").And("model", model).And("fields", fields)); this.authorizationService.authorizeForce(Permission.EditDmp); - Boolean isUpdate = this.conventionService.isValidGuid(model.getId()); + DmpEntity data = this.patchAndSave(model); - DmpEntity data; - if (isUpdate) { - data = this.entityManager.find(DmpEntity.class, model.getId()); - if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale())); - if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage()); - } else { - data = new DmpEntity(); - data.setId(UUID.randomUUID()); - data.setGroupId(UUID.randomUUID()); - data.setVersion((short) 1); - data.setIsActive(IsActive.Active); - data.setCreatedAt(Instant.now()); - } - - data.setLabel(model.getLabel()); - data.setStatus(model.getStatus()); - try { - data.setProperties(this.jsonHandlingService.toJson(model.getProperties())); - } catch (JsonProcessingException e) { - logger.error(e.getMessage(), e); - } - data.setDescription(model.getDescription()); - data.setUpdatedAt(Instant.now()); - if (isUpdate) - this.entityManager.merge(data); - else - this.entityManager.persist(data); - - this.entityManager.flush(); + this.patchAndSave(model.getReferences(), data.getId()); this.eventBroker.emit(new DmpTouchedEvent(data.getId())); - return this.builderFactory.builder(DmpBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(BaseFieldSet.build(fields, Dmp._id), data); + + return this.builderFactory.builder(DmpBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(BaseFieldSet.build(fields, Dmp._id, Dmp._hash), data); } public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException { @@ -156,8 +147,7 @@ public class DmpServiceImpl implements DmpService { latestVersionDmpEntityQuery.setOrder(new Ordering().addDescending(Dmp._version)); DmpEntity latestVersionDmpEntity = latestVersionDmpEntityQuery.first(); if (!latestVersionDmpEntity.getVersion().equals(oldDmpEntity.getVersion())){ - //TODO: (THGIANNOS) Create event for version conflict -// throw new MyValidationException(this.errors.getDescriptionTemplateNewVersionConflict().getCode(), this.errors.getDescriptionTemplateNewVersionConflict().getMessage()); + throw new MyValidationException(this.errors.getDmpNewVersionConflict().getCode(), this.errors.getDmpNewVersionConflict().getMessage()); } DmpEntity data = new DmpEntity(); @@ -180,4 +170,127 @@ public class DmpServiceImpl implements DmpService { return this.builderFactory.builder(DmpBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(BaseFieldSet.build(fields, Dmp._id), data); } + private DmpEntity patchAndSave(DmpPersist model) throws JsonProcessingException { + Boolean isUpdate = this.conventionService.isValidGuid(model.getId()); + + DmpEntity data; + if (isUpdate) { + data = this.entityManager.find(DmpEntity.class, model.getId()); + if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale())); + if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage()); + } else { + data = new DmpEntity(); + data.setId(UUID.randomUUID()); + data.setGroupId(UUID.randomUUID()); + data.setVersion((short) 1); + data.setIsActive(IsActive.Active); + data.setCreatedAt(Instant.now()); + } + + data.setLabel(model.getLabel()); + data.setStatus(model.getStatus()); + data.setProperties(this.jsonHandlingService.toJson(model.getProperties())); + data.setDescription(model.getDescription()); + data.setUpdatedAt(Instant.now()); + if (isUpdate) + this.entityManager.merge(data); + else + this.entityManager.persist(data); + + this.entityManager.flush(); + + return data; + } + + private void patchAndSave(List models, UUID dmpId) throws InvalidApplicationException { + if (models == null || models.isEmpty()) + return; + + List references = this.queryFactory.query(DmpReferenceQuery.class).dmpIds(dmpId).collect(); + Map> referencesLookup = this.conventionService.toDictionaryOfList(references, DmpReferenceEntity::getDmpId); + + List existingReferences; + if (referencesLookup.containsKey(dmpId)) + existingReferences = this.queryFactory.query(ReferenceQuery.class).ids(referencesLookup.get(dmpId).stream().map(DmpReferenceEntity::getId).toList()).collect(); + else + existingReferences = new ArrayList<>(); + + List updatedReferencesIds = models.stream().map(x -> x.getReference().getId()).filter(this.conventionService::isValidGuid).distinct().toList(); + List toDelete = existingReferences.stream().filter(x -> !updatedReferencesIds.contains(x.getId())).toList(); + List dmpReferenceRecordsToDelete = this.queryFactory.query(DmpReferenceQuery.class).referenceIds(toDelete.stream().map(ReferenceEntity::getId).toList()).collect(); + this.deleterFactory.deleter(DmpReferenceDeleter.class).delete(dmpReferenceRecordsToDelete); + + Map existingReferencesLookup = existingReferences.stream().collect(Collectors.toMap(ReferenceEntity::getId, x -> x)); + + for (DmpReferencePersist model : models) { + ReferencePersist referenceModel = model.getReference(); + + Boolean isUpdate = this.conventionService.isValidGuid(referenceModel.getId()); + + ReferenceEntity data; + if (isUpdate) { + if (!existingReferencesLookup.containsKey(referenceModel.getId())) + throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{referenceModel.getId(), Reference.class.getSimpleName()}, LocaleContextHolder.getLocale())); + data = existingReferencesLookup.get(referenceModel.getId()); + if (data == null) + throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{referenceModel.getId(), Reference.class.getSimpleName()}, LocaleContextHolder.getLocale())); + if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(referenceModel.getHash())) + throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage()); + } else { + data = new ReferenceEntity(); + data.setId(UUID.randomUUID()); + data.setIsActive(IsActive.Active); + data.setCreatedAt(Instant.now()); + + DmpReferenceEntity dmpReference = new DmpReferenceEntity(); + dmpReference.setReferenceId(data.getId()); + dmpReference.setDmpId(dmpId); + dmpReference.setCreatedAt(Instant.now()); + dmpReference.setUpdatedAt(Instant.now()); + dmpReference.setIsActive(IsActive.Active); + dmpReference.setData(model.getData()); + this.entityManager.persist(dmpReference); + } + + data.setDefinition(this.xmlHandlingService.toXmlSafe(this.buildDefinitionEntity(referenceModel.getDefinition()))); + data.setUpdatedAt(Instant.now()); + data.setReference(referenceModel.getReference()); + data.setAbbreviation(referenceModel.getAbbreviation()); + data.setSource(referenceModel.getSource()); + data.setSourceType(referenceModel.getSourceType()); + + if (isUpdate) + this.entityManager.merge(data); + else + this.entityManager.persist(data); + + } + this.entityManager.flush(); + + } + + private @NotNull DefinitionEntity buildDefinitionEntity(DefinitionPersist persist){ + DefinitionEntity data = new DefinitionEntity(); + if (persist == null) return data; + if (!this.conventionService.isListNullOrEmpty(persist.getFields())){ + data.setFields(new ArrayList<>()); + for (FieldPersist fieldPersist: persist.getFields()) { + data.getFields().add(this.buildFieldEntity(fieldPersist)); + } + } + + return data; + } + + private @NotNull FieldEntity buildFieldEntity(FieldPersist persist){ + FieldEntity data = new FieldEntity(); + if (persist == null) return data; + + data.setCode(persist.getCode()); + data.setDataType(persist.getDataType()); + data.setCode(persist.getCode()); + + return data; + } + } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/supportivematerial/SupportiveMaterialService.java b/dmp-backend/core/src/main/java/eu/eudat/service/supportivematerial/SupportiveMaterialService.java index 3a1bafc79..57396f1ae 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/supportivematerial/SupportiveMaterialService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/supportivematerial/SupportiveMaterialService.java @@ -1,70 +1,27 @@ package eu.eudat.service.supportivematerial; +import eu.eudat.model.SupportiveMaterial; import eu.eudat.model.persist.SupportiveMaterialPersist; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Service; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyForbiddenException; +import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.exception.MyValidationException; +import gr.cite.tools.fieldset.FieldSet; -import java.io.*; -import java.nio.file.Files; +import javax.management.InvalidApplicationException; +import java.io.IOException; import java.nio.file.Path; -import java.util.List; -import java.util.stream.Collectors; +import java.util.UUID; import java.util.stream.Stream; +import jakarta.xml.bind.JAXBException; +import org.springframework.http.ResponseEntity; -@Service -public class SupportiveMaterialService { +public interface SupportiveMaterialService { - private final SupportiveMaterialCacheService supportiveMaterialCacheService; + ResponseEntity getResponseEntity(String lang, Stream paths) throws IOException; - public SupportiveMaterialService( - SupportiveMaterialCacheService supportiveMaterialCacheService - ) { - this.supportiveMaterialCacheService = supportiveMaterialCacheService; - } + SupportiveMaterial persist(SupportiveMaterialPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException; - public ResponseEntity getResponseEntity(String lang, Stream paths) throws IOException { - List result = paths.filter(Files::isRegularFile) - .map(Path::toString).collect(Collectors.toList()); - - String fileName = result.stream().filter(about -> about.contains("_" + lang)).findFirst().orElse(null); - - if (fileName == null) { - fileName = result.stream().filter(about -> about.contains("_en")).findFirst().get(); - } - - SupportiveMaterialCacheService.SupportiveMaterialCacheValue supportiveMaterialCacheItem = this.supportiveMaterialCacheService.lookup(this.supportiveMaterialCacheService.buildKey(fileName)); - - if(supportiveMaterialCacheItem == null){ - InputStream is = new FileInputStream(fileName); - - // Path path = Paths.get(fileName); - - byte[] content = new byte[is.available()]; - is.read(content); - is.close(); - - supportiveMaterialCacheItem = new SupportiveMaterialCacheService.SupportiveMaterialCacheValue(fileName, content); - this.supportiveMaterialCacheService.put(supportiveMaterialCacheItem); - } - - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.setContentLength(supportiveMaterialCacheItem.getContent().length); - responseHeaders.setContentType(MediaType.TEXT_HTML); - responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName); - responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); - responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); - - return new ResponseEntity<>(supportiveMaterialCacheItem.getContent(), responseHeaders, HttpStatus.OK); - } - - public void persist(SupportiveMaterialPersist model) throws IOException { - this.supportiveMaterialCacheService.evict(model.getName()); - OutputStream os = new FileOutputStream(model.getName()); - os.write(model.getHtml().getBytes()); - os.close(); - } + void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/supportivematerial/SupportiveMaterialServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/supportivematerial/SupportiveMaterialServiceImpl.java new file mode 100644 index 000000000..a51fef853 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/supportivematerial/SupportiveMaterialServiceImpl.java @@ -0,0 +1,166 @@ +package eu.eudat.service.supportivematerial; + +import com.fasterxml.jackson.core.JsonProcessingException; +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.authorization.Permission; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.SupportiveMaterialEntity; +import eu.eudat.model.SupportiveMaterial; +import eu.eudat.model.builder.SupportiveMaterialBuilder; +import eu.eudat.model.deleter.SupportiveMaterialDeleter; +import eu.eudat.model.persist.SupportiveMaterialPersist; +import eu.eudat.query.SupportiveMaterialQuery; +import eu.eudat.service.dmpblueprint.DmpBlueprintServiceImpl; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.deleter.DeleterFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyForbiddenException; +import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.exception.MyValidationException; +import gr.cite.tools.fieldset.BaseFieldSet; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import jakarta.persistence.EntityManager; +import jakarta.xml.bind.JAXBException; +import org.slf4j.LoggerFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; + +import javax.management.InvalidApplicationException; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Instant; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +@Service +public class SupportiveMaterialServiceImpl implements SupportiveMaterialService{ + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpBlueprintServiceImpl.class)); + private final EntityManager entityManager; + private final AuthorizationService authorizationService; + private final DeleterFactory deleterFactory; + private final BuilderFactory builderFactory; + private final ConventionService conventionService; + private final MessageSource messageSource; + private final QueryFactory queryFactory; + private final SupportiveMaterialCacheService supportiveMaterialCacheService; + + public SupportiveMaterialServiceImpl( + EntityManager entityManager, AuthorizationService authorizationService, DeleterFactory deleterFactory, BuilderFactory builderFactory, + ConventionService conventionService, MessageSource messageSource, QueryFactory queryFactory, + SupportiveMaterialCacheService supportiveMaterialCacheService + ) { + this.entityManager = entityManager; + this.authorizationService = authorizationService; + this.deleterFactory = deleterFactory; + this.builderFactory = builderFactory; + this.conventionService = conventionService; + this.messageSource = messageSource; + this.queryFactory = queryFactory; + this.supportiveMaterialCacheService = supportiveMaterialCacheService; + } + + public ResponseEntity getResponseEntity(String lang, Stream paths) throws IOException { + List result = paths.filter(Files::isRegularFile) + .map(Path::toString).collect(Collectors.toList()); + + String fileName = result.stream().filter(about -> about.contains("_" + lang)).findFirst().orElse(null); + + if (fileName == null) { + fileName = result.stream().filter(about -> about.contains("_en")).findFirst().get(); + } + + SupportiveMaterialCacheService.SupportiveMaterialCacheValue supportiveMaterialCacheItem = this.supportiveMaterialCacheService.lookup(this.supportiveMaterialCacheService.buildKey(fileName)); + + if(supportiveMaterialCacheItem == null){ + InputStream is = new FileInputStream(fileName); + + // Path path = Paths.get(fileName); + + byte[] content = new byte[is.available()]; + is.read(content); + is.close(); + + supportiveMaterialCacheItem = new SupportiveMaterialCacheService.SupportiveMaterialCacheValue(fileName, content); + this.supportiveMaterialCacheService.put(supportiveMaterialCacheItem); + } + + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.setContentLength(supportiveMaterialCacheItem.getContent().length); + responseHeaders.setContentType(MediaType.TEXT_HTML); + responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName); + responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); + responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); + + return new ResponseEntity<>(supportiveMaterialCacheItem.getContent(), responseHeaders, HttpStatus.OK); + } + +// public void persist(SupportiveMaterialPersist model) throws IOException { +// this.supportiveMaterialCacheService.evict(model.getName()); +// OutputStream os = new FileOutputStream(model.getName()); +// os.write(model.getHtml().getBytes()); +// os.close(); +// } + + public SupportiveMaterial persist(SupportiveMaterialPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException{ + logger.debug(new MapLogEntry("persisting data").And("model", model).And("fields", fields)); + + this.authorizationService.authorizeForce(Permission.EditSupportiveMaterial); + + Boolean isUpdate = this.conventionService.isValidGuid(model.getId()); + + SupportiveMaterialEntity data; + if (isUpdate) { + data = this.entityManager.find(SupportiveMaterialEntity.class, model.getId()); + if (data == null) + throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), SupportiveMaterial.class.getSimpleName()}, LocaleContextHolder.getLocale())); + } else { + List datas = this.queryFactory.query(SupportiveMaterialQuery.class).authorize(AuthorizationFlags.OwnerOrPermission).languageCodes(model.getLanguageCode()).types(model.getType()).collect(); + + if(datas != null && !datas.isEmpty()){ + throw new MyApplicationException("Could not create a new Data with same type and lang code !"); + } + + data = new SupportiveMaterialEntity(); + data.setId(UUID.randomUUID()); + data.setIsActive(IsActive.Active); + data.setCreatedAt(Instant.now()); + } + + data.setType(model.getType()); + data.setLanguageCode(model.getLanguageCode()); + data.setPayload(model.getPayload()); + data.setUpdatedAt(Instant.now()); + + if (isUpdate) this.entityManager.merge(data); + else this.entityManager.persist(data); + + this.entityManager.flush(); + + return this.builderFactory.builder(SupportiveMaterialBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(BaseFieldSet.build(fields, SupportiveMaterial._id), data); + } + + public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException { + logger.debug("deleting : {}", id); + + this.authorizationService.authorizeForce(Permission.DeleteSupportiveMaterial); + + this.deleterFactory.deleter(SupportiveMaterialDeleter.class).deleteAndSaveByIds(List.of(id)); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/pdf/PDFUtils.java b/dmp-backend/core/src/main/java/eu/eudat/utilities/pdf/PDFUtils.java similarity index 81% rename from dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/pdf/PDFUtils.java rename to dmp-backend/core/src/main/java/eu/eudat/utilities/pdf/PDFUtils.java index 6f842b1f3..8e2170c65 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/pdf/PDFUtils.java +++ b/dmp-backend/core/src/main/java/eu/eudat/utilities/pdf/PDFUtils.java @@ -1,6 +1,6 @@ -package eu.eudat.logic.utilities.documents.pdf; +package eu.eudat.utilities.pdf; -import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; +import eu.eudat.model.file.FileEnvelope; import org.apache.commons.io.IOUtils; import org.springframework.core.env.Environment; import org.springframework.core.io.FileSystemResource; @@ -18,6 +18,13 @@ import java.util.UUID; public class PDFUtils { + public static File convertToPDF(eu.eudat.depositinterface.models.FileEnvelope file, Environment environment) throws IOException { + FileEnvelope envelope = new FileEnvelope(); + envelope.setFilename(file.getFilename()); + envelope.setFile(file.getFile()); + return convertToPDF(envelope, environment); + } + public static File convertToPDF(FileEnvelope file, Environment environment) throws IOException { LinkedMultiValueMap map = new LinkedMultiValueMap<>(); String uuid = UUID.randomUUID().toString(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java index 928e421a0..f67975d19 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java @@ -17,8 +17,8 @@ import eu.eudat.logic.managers.DataManagementPlanManager; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.DatabaseRepository; -import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; -import eu.eudat.logic.utilities.documents.pdf.PDFUtils; +import eu.eudat.model.file.FileEnvelope; +import eu.eudat.utilities.pdf.PDFUtils; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; import eu.eudat.models.data.datasetwizard.DatasetsToBeFinalized; import eu.eudat.models.data.dmp.DataManagementPlan; diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java index 3cea26486..7d63d122c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java @@ -19,8 +19,8 @@ import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.services.forms.VisibilityRuleServiceImpl; -import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; -import eu.eudat.logic.utilities.documents.pdf.PDFUtils; +import eu.eudat.model.file.FileEnvelope; +import eu.eudat.utilities.pdf.PDFUtils; import eu.eudat.models.data.dataset.DatasetOverviewModel; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; import eu.eudat.models.data.datasetwizard.DataManagentPlanListingModel; diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java index 390b1f96c..9c7111631 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java @@ -3,10 +3,10 @@ package eu.eudat.controllers; import eu.eudat.authorization.Permission; import eu.eudat.logic.managers.DepositManager; import eu.eudat.logic.services.ApiContext; -import eu.eudat.models.data.doi.DepositCode; -import eu.eudat.models.data.doi.DepositRequest; -import eu.eudat.models.data.doi.Doi; -import eu.eudat.models.data.doi.RepositoryConfig; +import eu.eudat.model.doi.DepositCode; +import eu.eudat.model.doi.DepositRequest; +import eu.eudat.model.doi.Doi; +import eu.eudat.model.doi.RepositoryConfig; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.types.ApiMessageCode; import gr.cite.commons.web.authz.service.AuthorizationService; diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/FileController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/FileController.java index 71ca835ef..0b6075808 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/FileController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/FileController.java @@ -8,24 +8,23 @@ import eu.eudat.commons.scope.user.UserScope; import eu.eudat.commons.types.descriptiontemplate.DefinitionEntity; import eu.eudat.commons.types.descriptiontemplate.FieldEntity; import eu.eudat.commons.types.descriptiontemplate.fielddata.UploadDataEntity; -import eu.eudat.data.DescriptionTemplateEntity; import eu.eudat.data.DescriptionEntity; -import eu.eudat.data.DmpEntity; +import eu.eudat.data.DescriptionTemplateEntity; import eu.eudat.data.old.DMP; import eu.eudat.data.old.FileUpload; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.managers.DatasetProfileManager; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.DatabaseRepository; -import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; +import eu.eudat.model.file.FileEnvelope; import eu.eudat.models.HintedModelFactory; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.query.DescriptionTemplateQuery; -import eu.eudat.query.DmpQuery; import eu.eudat.types.ApiMessageCode; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.QueryFactory; +import jakarta.transaction.Transactional; import jakarta.xml.bind.JAXBException; import org.apache.poi.util.IOUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -37,8 +36,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.util.unit.DataSize; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; - -import jakarta.transaction.Transactional; import org.xml.sax.SAXException; import javax.management.InvalidApplicationException; diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DmpController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DmpController.java index f2d323e53..21fa1d814 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DmpController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DmpController.java @@ -1,5 +1,6 @@ package eu.eudat.controllers.v2; +import com.fasterxml.jackson.core.JsonProcessingException; import eu.eudat.audit.AuditableAction; import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.data.DmpEntity; @@ -102,7 +103,7 @@ public class DmpController { @PostMapping("persist") @Transactional - public Dmp Persist(@MyValidate @RequestBody DmpPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { + public Dmp Persist(@MyValidate @RequestBody DmpPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JsonProcessingException { logger.debug(new MapLogEntry("persisting" + Dmp.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet)); Dmp persisted = this.dmpService.persist(model, fieldSet); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/SupportiveMaterialController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/SupportiveMaterialController.java index c8c992066..c0bb8785a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/SupportiveMaterialController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/SupportiveMaterialController.java @@ -1,62 +1,158 @@ package eu.eudat.controllers.v2; -import eu.eudat.authorization.Permission; +import com.fasterxml.jackson.core.JsonProcessingException; +import eu.eudat.audit.AuditableAction; +import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.commons.enums.SupportiveMaterialFieldType; -import eu.eudat.logic.managers.MetricsManager; +import eu.eudat.data.SupportiveMaterialEntity; +import eu.eudat.model.SupportiveMaterial; +import eu.eudat.model.builder.SupportiveMaterialBuilder; +import eu.eudat.model.censorship.SupportiveMaterialCensor; import eu.eudat.model.persist.SupportiveMaterialPersist; -import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.model.result.QueryResult; +import eu.eudat.query.SupportiveMaterialQuery; +import eu.eudat.query.lookup.SupportiveMaterialLookup; import eu.eudat.service.supportivematerial.SupportiveMaterialService; -import eu.eudat.types.ApiMessageCode; +import eu.eudat.service.supportivematerial.SupportiveMaterialServiceImpl; import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.auditing.AuditService; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.censor.CensorFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyForbiddenException; +import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import gr.cite.tools.validation.MyValidate; +import jakarta.transaction.Transactional; +import jakarta.xml.bind.JAXBException; import org.apache.commons.lang3.EnumUtils; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.core.env.Environment; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import javax.management.InvalidApplicationException; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerException; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Locale; -import java.util.Objects; +import java.util.*; import java.util.stream.Stream; @RestController -@RequestMapping(path = {"/api/material"}) +@RequestMapping(path = {"/api/supportive-material"}) public class SupportiveMaterialController { + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(SupportiveMaterialController.class)); private Environment environment; - private SupportiveMaterialService supportiveMaterialService; + private final BuilderFactory builderFactory; + private final AuditService auditService; + + private final CensorFactory censorFactory; + private final QueryFactory queryFactory; + private final MessageSource messageSource; + private final SupportiveMaterialService supportiveMaterialService; private final AuthorizationService authorizationService; @Autowired - public SupportiveMaterialController(Environment environment, SupportiveMaterialService supportiveMaterialService, MetricsManager metricsManager, AuthorizationService authorizationService) { + public SupportiveMaterialController(Environment environment, SupportiveMaterialService supportiveMaterialService, BuilderFactory builderFactory, + AuditService auditService, CensorFactory censorFactory, QueryFactory queryFactory, MessageSource messageSource, + AuthorizationService authorizationService) { this.environment = environment; this.supportiveMaterialService = supportiveMaterialService; + this.builderFactory = builderFactory; + this.auditService = auditService; + this.censorFactory = censorFactory; + this.queryFactory = queryFactory; + this.messageSource = messageSource; this.authorizationService = authorizationService; } - @GetMapping("{lang}") - public ResponseEntity getMaterial(@PathVariable(name = "lang") String lang, int field) throws IOException { - if( !EnumUtils.isValidEnum(SupportiveMaterialFieldType.class, SupportiveMaterialFieldType.of((short) field).name())){ - return new ResponseEntity<>(HttpStatus.NOT_FOUND); + @PostMapping("query") + public QueryResult query(@RequestBody SupportiveMaterialLookup lookup) throws MyApplicationException, MyForbiddenException { + logger.debug("querying {}", SupportiveMaterial.class.getSimpleName()); + + this.censorFactory.censor(SupportiveMaterialCensor.class).censor(lookup.getProject(), null); + + SupportiveMaterialQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrPermission); + List datas = query.collectAs(lookup.getProject()); + List models = this.builderFactory.builder(SupportiveMaterialBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(lookup.getProject(), datas); + long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size(); + + this.auditService.track(AuditableAction.SupportiveMaterial_Query, "lookup", lookup); + + return new QueryResult(models, count); + } + + @GetMapping("{id}") + public SupportiveMaterial get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException { + logger.debug(new MapLogEntry("retrieving " + SupportiveMaterial.class.getSimpleName()).And("id", id).And("fields", fieldSet)); + + this.censorFactory.censor(SupportiveMaterialCensor.class).censor(fieldSet, null); + + SupportiveMaterialQuery query = this.queryFactory.query(SupportiveMaterialQuery.class).authorize(AuthorizationFlags.OwnerOrPermission).ids(id); + SupportiveMaterial model = this.builderFactory.builder(SupportiveMaterialBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(fieldSet, query.firstAs(fieldSet)); + if (model == null) + throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, SupportiveMaterial.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + this.auditService.track(AuditableAction.SupportiveMaterial_Lookup, Map.ofEntries( + new AbstractMap.SimpleEntry("id", id), + new AbstractMap.SimpleEntry("fields", fieldSet) + )); + + return model; + } + + @PostMapping("public") + public ResponseEntity queryPublic(@RequestBody SupportiveMaterialLookup lookup) throws IOException { + logger.debug("querying {}", SupportiveMaterial.class.getSimpleName()); + + this.censorFactory.censor(SupportiveMaterialCensor.class).censor(lookup.getProject(), null); + + SupportiveMaterialQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrPermission); + List datas = query.collectAs(lookup.getProject()); + if (datas.size() == 1){ + return new ResponseEntity<>(datas.get(0).getPayload().getBytes(), HttpStatus.OK); } - try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty(SupportiveMaterialFieldType.of((short) field).name().toLowerCase() +".path"))))) { - return this.supportiveMaterialService.getResponseEntity(lang, paths); + try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty(lookup.getTypes().stream().toList().get(0).name().toLowerCase() +".path"))))) { + return this.supportiveMaterialService.getResponseEntity(lookup.getLanguageCodes().get(0), paths); } } - @PostMapping("persist") - public @ResponseBody - ResponseEntity> persist(@RequestBody SupportiveMaterialPersist model) throws IOException { - this.authorizationService.authorizeForce(Permission.AdminRole); - //String fileName = this.environment.getProperty(model.getName()+ ".path"); - this.supportiveMaterialService.persist(model); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Updated").payload("Updated")); + @PostMapping("persist") + @Transactional + public SupportiveMaterial persist(@MyValidate @RequestBody SupportiveMaterialPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, JAXBException, ParserConfigurationException, JsonProcessingException, TransformerException { + logger.debug(new MapLogEntry("persisting" + SupportiveMaterial.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet)); + this.censorFactory.censor(SupportiveMaterialCensor.class).censor(fieldSet, null); + + SupportiveMaterial persisted = this.supportiveMaterialService.persist(model, fieldSet); + + this.auditService.track(AuditableAction.SupportiveMaterial_Persist, Map.ofEntries( + new AbstractMap.SimpleEntry("model", model), + new AbstractMap.SimpleEntry("fields", fieldSet) + )); + return persisted; + } + + @DeleteMapping("{id}") + @Transactional + public void delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException { + logger.debug(new MapLogEntry("retrieving" + SupportiveMaterial.class.getSimpleName()).And("id", id)); + + this.supportiveMaterialService.deleteAndSave(id); + + this.auditService.track(AuditableAction.SupportiveMaterial_Delete, "id", id); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index 235db7ff4..b185a60a7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -40,25 +40,25 @@ import eu.eudat.logic.builders.entity.UserInfoBuilder; import eu.eudat.logic.mapper.elastic.DmpMapper; import eu.eudat.logic.mapper.elastic.criteria.DmpCriteriaMapper; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; -import eu.eudat.logic.security.repositorydeposit.mapper.DMPToDepositMapper; +import eu.eudat.model.mapper.deposit.DMPToDepositMapper; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.services.forms.VisibilityRuleServiceImpl; import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.commons.types.xml.XmlBuilder; -import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; -import eu.eudat.logic.utilities.documents.pdf.PDFUtils; +import eu.eudat.model.file.FileEnvelope; +import eu.eudat.utilities.pdf.PDFUtils; import eu.eudat.logic.utilities.documents.types.ParagraphStyle; import eu.eudat.logic.utilities.documents.word.WordBuilder; import eu.eudat.logic.utilities.documents.xml.ExportXmlBuilder; +import eu.eudat.model.doi.DepositRequest; +import eu.eudat.model.doi.Doi; import eu.eudat.models.HintedModelFactory; import eu.eudat.models.data.dataset.DatasetOverviewModel; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.datasetwizard.DatasetsToBeFinalized; import eu.eudat.models.data.dmp.*; -import eu.eudat.models.data.doi.DepositRequest; -import eu.eudat.models.data.doi.Doi; import eu.eudat.models.data.dynamicfields.DynamicFieldWithValue; import eu.eudat.models.data.funder.FunderDMPEditorModel; import eu.eudat.models.data.grant.GrantDMPEditorModel; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index 7fc2fdef4..be8734b07 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -36,7 +36,7 @@ import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.services.forms.VisibilityRuleServiceImpl; import eu.eudat.logic.services.operations.DatabaseRepository; -import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; +import eu.eudat.model.file.FileEnvelope; import eu.eudat.logic.utilities.documents.types.ParagraphStyle; import eu.eudat.logic.utilities.documents.word.WordBuilder; import eu.eudat.logic.utilities.documents.xml.ExportXmlBuilder; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java index 10061375c..75ec14229 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java @@ -2,9 +2,9 @@ package eu.eudat.logic.managers; import eu.eudat.depositinterface.repository.RepositoryDeposit; import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; -import eu.eudat.models.data.doi.DepositRequest; -import eu.eudat.models.data.doi.Doi; -import eu.eudat.models.data.doi.RepositoryConfig; +import eu.eudat.model.doi.DepositRequest; +import eu.eudat.model.doi.Doi; +import eu.eudat.model.doi.RepositoryConfig; import jakarta.transaction.Transactional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java index 124468e37..e9d6f4a4f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java @@ -7,9 +7,9 @@ import eu.eudat.commons.enums.IsActive; import eu.eudat.data.DescriptionEntity; import eu.eudat.data.DmpBlueprintEntity; import eu.eudat.data.old.*; +import eu.eudat.model.doi.Doi; import eu.eudat.models.DataModel; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; -import eu.eudat.models.data.doi.Doi; import eu.eudat.models.data.dynamicfields.DynamicFieldWithValue; import eu.eudat.models.data.funder.Funder; import eu.eudat.models.data.helpermodels.Tuple; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java index fdded6905..aeea68b25 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java @@ -6,13 +6,12 @@ import eu.eudat.commons.enums.DescriptionStatus; import eu.eudat.commons.enums.IsActive; import eu.eudat.data.old.DMP; import eu.eudat.data.old.DMPDatasetProfile; -import eu.eudat.data.DescriptionEntity; +import eu.eudat.model.doi.Doi; import eu.eudat.models.DataModel; import eu.eudat.models.data.dataset.DatasetOverviewModel; import eu.eudat.models.data.dmp.AssociatedProfile; import eu.eudat.models.data.dmp.Organisation; import eu.eudat.models.data.dmp.Researcher; -import eu.eudat.models.data.doi.Doi; import eu.eudat.models.data.grant.GrantOverviewModel; import java.util.*; diff --git a/dmp-backend/web/src/main/resources/config/cache.yml b/dmp-backend/web/src/main/resources/config/cache.yml index 637bb3033..0464d8c83 100644 --- a/dmp-backend/web/src/main/resources/config/cache.yml +++ b/dmp-backend/web/src/main/resources/config/cache.yml @@ -34,6 +34,14 @@ cache: expireAfterWriteMinutes: 10 expireAfterAccessMinutes: 10 refreshAfterWriteMinutes: 10 + - names: [ "deposit" ] + allowNullValues: true + initialCapacity: 100 + maximumSize: 500 + enableRecordStats: false + expireAfterWriteMinutes: 10 + expireAfterAccessMinutes: 10 + refreshAfterWriteMinutes: 10 mapCaches: apiKey: name: apikey @@ -46,4 +54,7 @@ cache: keyPattern: supportive_material_$material$:v0 Reference: name: Reference - keyPattern: reference_$type$_$criteria$:v0 \ No newline at end of file + keyPattern: reference_$type$_$criteria$:v0 + deposit: + name: deposit + keyPattern: base:v0 \ No newline at end of file diff --git a/dmp-backend/web/src/main/resources/config/errors.yml b/dmp-backend/web/src/main/resources/config/errors.yml index e566b2f1a..4e7d42118 100644 --- a/dmp-backend/web/src/main/resources/config/errors.yml +++ b/dmp-backend/web/src/main/resources/config/errors.yml @@ -29,3 +29,6 @@ error-thesaurus: description-template-new-version-conflict: code: 114 message: version to update not the latest + dmp-new-version-conflict: + code: 115 + message: version to update not the latest diff --git a/dmp-backend/web/src/main/resources/config/permissions.yml b/dmp-backend/web/src/main/resources/config/permissions.yml index a7707d181..1d2f618c9 100644 --- a/dmp-backend/web/src/main/resources/config/permissions.yml +++ b/dmp-backend/web/src/main/resources/config/permissions.yml @@ -300,6 +300,49 @@ permissions: allowAnonymous: false allowAuthenticated: false + # SupportiveMaterial Permissions + BrowseSupportiveMaterial: + roles: + - Admin + clients: [ ] + allowAnonymous: yes + allowAuthenticated: yes + EditSupportiveMaterial: + roles: + - Admin + clients: [ ] + allowAnonymous: false + allowAuthenticated: false + DeleteSupportiveMaterial: + roles: + - Admin + claims: [ ] + clients: [ ] + allowAnonymous: false + allowAuthenticated: false + + + # DmpDescriptionTemplate Permissions + BrowseDmpDescriptionTemplate: + roles: + - Admin + clients: [ ] + allowAnonymous: false + allowAuthenticated: false + EditDmpDescriptionTemplate: + roles: + - Admin + clients: [ ] + allowAnonymous: false + allowAuthenticated: false + DeleteDmpDescriptionTemplate: + roles: + - Admin + claims: [ ] + clients: [ ] + allowAnonymous: false + allowAuthenticated: false + # DescriptionReference Permissions BrowseDescriptionReference: roles: diff --git a/dmp-backend/web/src/main/resources/material/about/About_gr.html b/dmp-backend/web/src/main/resources/material/about/About_gr.html deleted file mode 100644 index c2bfd135c..000000000 --- a/dmp-backend/web/src/main/resources/material/about/About_gr.html +++ /dev/null @@ -1,17 +0,0 @@ -

 

-

- - -

-
-
-
-

Σχετικά με το Argos

-
-
-
-
-

Το ARGOS είναι ένα διαδικτυακό εργαλείο για την υποστήριξη αυτοματοποιημένων διαδικασιών για τη δημιουργία, τη διαχείριση, την κοινή χρήση και τη σύνδεση των DMP με ερευνητικά αντικείμενα στα οποία αντιστοιχούν. Αποτελεί κοινή προσπάθεια του OpenAIRE και της EUDAT να παραδώσουν μια ανοιχτή πλατφόρμα για τον Σχεδιασμό Διαχείρισης Δεδομένων που να αντιμετωπίζει τις βέλτιστες πρακτικές FAIR και Open και να μην προϋποθέτει εμπόδια για τη χρήση και την υιοθέτησή της. Το κάνει εφαρμόζοντας κοινά πρότυπα για μηχανικά ενεργά DMPs, όπως ορίζονται από την παγκόσμια κοινότητα ερευνητικών δεδομένων της RDA και επικοινωνώντας και διαβουλεύοντας τους ερευνητές, τις ερευνητικές κοινότητες και τους χρηματοδότες για να προβληματιστούν καλύτερα για τις ανάγκες τους.

Το ARGOS παρέχει ένα ευέλικτο περιβάλλον και μια εύκολη διεπαφή για την πλοήγηση και χρήση των χρηστών.

-
-
-
\ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/supportive-material/supportive-material.ts b/dmp-frontend/src/app/core/model/supportive-material/supportive-material.ts index e3501146f..8af5d0892 100644 --- a/dmp-frontend/src/app/core/model/supportive-material/supportive-material.ts +++ b/dmp-frontend/src/app/core/model/supportive-material/supportive-material.ts @@ -1,7 +1,21 @@ +import { IsActive } from "@app/core/common/enum/is-active.enum"; import { SupportiveMaterialFieldType } from "@app/core/common/enum/supportive-material-field-type"; +import { Guid } from "@common/types/guid"; + +export interface SupportiveMaterial{ + id: Guid; + type: SupportiveMaterialFieldType; + languageCode: string; + payload: string; + createdAt: Date; + updatedAt: Date; + isActive: IsActive; +} + export interface SupportiveMaterialPersist{ - name: string; + id: Guid; type: SupportiveMaterialFieldType; - html: string; + languageCode: string; + payload: string; } \ No newline at end of file diff --git a/dmp-frontend/src/app/core/query/supportive-material.lookup.ts b/dmp-frontend/src/app/core/query/supportive-material.lookup.ts new file mode 100644 index 000000000..43537e1a4 --- /dev/null +++ b/dmp-frontend/src/app/core/query/supportive-material.lookup.ts @@ -0,0 +1,26 @@ +import { Lookup } from '@common/model/lookup'; +import { Guid } from '@common/types/guid'; +import { IsActive } from '../common/enum/is-active.enum'; +import { SupportiveMaterialFieldType } from '../common/enum/supportive-material-field-type'; + +export class SupportiveMaterialLookup extends Lookup implements SupportiveMaterialFilter { + ids: Guid[]; + excludedIds: Guid[]; + like: string; + isActive: IsActive[]; + types: SupportiveMaterialFieldType[]; + languageCodes: string[]; + + constructor() { + super(); + } +} + +export interface SupportiveMaterialFilter { + ids: Guid[]; + excludedIds: Guid[]; + like: string; + isActive: IsActive[]; + types: SupportiveMaterialFieldType[]; + languageCodes: string[]; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/supportive-material/supportive-material.service.ts b/dmp-frontend/src/app/core/services/supportive-material/supportive-material.service.ts index 9defff094..d5f82c30a 100644 --- a/dmp-frontend/src/app/core/services/supportive-material/supportive-material.service.ts +++ b/dmp-frontend/src/app/core/services/supportive-material/supportive-material.service.ts @@ -1,10 +1,16 @@ import { Injectable } from "@angular/core"; import { ConfigurationService } from "../configuration/configuration.service"; import { HttpClient, HttpResponse } from "@angular/common/http"; -import { Observable } from "rxjs"; -import { SupportiveMaterialFieldType } from "@app/core/common/enum/supportive-material-field-type"; -import { SupportiveMaterialPersist } from "@app/core/model/supportive-material/supportive-material"; +import { Observable, throwError } from "rxjs"; +import { SupportiveMaterial, SupportiveMaterialPersist } from "@app/core/model/supportive-material/supportive-material"; import { BaseHttpV2Service } from "../http/base-http-v2.service"; +import { SupportiveMaterialLookup } from "@app/core/query/supportive-material.lookup"; +import { QueryResult } from "@common/model/query-result"; +import { catchError } from "rxjs/operators"; +import { Guid } from "@common/types/guid"; +import { nameof } from "ts-simple-nameof"; +import { IsActive } from "@app/core/common/enum/is-active.enum"; +import { SupportiveMaterialFieldType } from "@app/core/common/enum/supportive-material-field-type"; @Injectable() export class SupportiveMaterialService{ @@ -15,13 +21,63 @@ export class SupportiveMaterialService{ ) { } - private get apiBase(): string { return `${this.configurationService.server}material`; } + private get apiBase(): string { return `${this.configurationService.server}supportive-material`; } - public getMaterial(lang: string, field: number): Observable> { - return this.http.get(`${this.apiBase}/${lang}`, {params: {field}, responseType: 'blob', observe: 'response' }); + queryPublic(q: SupportiveMaterialLookup): Observable> { + return this.http.post>(`${this.apiBase}/public`, q , {responseType: 'blob', observe: 'response' }); } - public persist(item :SupportiveMaterialPersist): Observable { - return this.http.post(`${this.apiBase}/persist`, item); + query(q: SupportiveMaterialLookup): Observable> { + const url = `${this.apiBase}/query`; + return this.http.post>(url, q).pipe(catchError((error: any) => throwError(error))); } + + getSingle(id: Guid, reqFields: string[] = []): Observable { + const url = `${this.apiBase}/${id}`; + const options = { params: { f: reqFields } }; + + return this.http + .get(url, options).pipe( + catchError((error: any) => throwError(error))); + } + + persist(item: SupportiveMaterialPersist): Observable { + const url = `${this.apiBase}/persist`; + + return this.http + .post(url, item).pipe( + catchError((error: any) => throwError(error))); + } + + delete(id: Guid): Observable { + const url = `${this.apiBase}/${id}`; + + return this.http + .delete(url).pipe( + catchError((error: any) => throwError(error))); + } + + + // LOOKUP + + public static DefaultSupportiveMaterialLookup(): SupportiveMaterialLookup{ + const lookup = new SupportiveMaterialLookup(); + + lookup.project = { + fields: [ + nameof(x => x.id), + nameof(x => x.type), + nameof(x => x.languageCode), + nameof(x => x.payload), + nameof(x => x.createdAt), + nameof(x => x.updatedAt), + nameof(x => x.isActive) + ] + }; + lookup.order = { items: [nameof(x => x.type)] }; + lookup.page = { offset: 0, size: 10 }; + lookup.isActive = [IsActive.Active]; + return lookup; + } + } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/about/about.component.ts b/dmp-frontend/src/app/ui/about/about.component.ts index 0325ab24d..e7799089e 100644 --- a/dmp-frontend/src/app/ui/about/about.component.ts +++ b/dmp-frontend/src/app/ui/about/about.component.ts @@ -33,7 +33,11 @@ export class AboutComponent extends BaseComponent implements OnInit { this.translate.onLangChange.subscribe((event: LangChangeEvent) => { this.router.navigate(['/reload'], { skipLocationChange: true }).then(() => this.router.navigate(['/about'])); }); - this.supportiveMaterialService.getMaterial(this.languageService.getCurrentLanguage(), SupportiveMaterialFieldType.About) + const lookup = SupportiveMaterialService.DefaultSupportiveMaterialLookup(); + lookup.languageCodes = [this.languageService.getCurrentLanguage()]; + lookup.types = [SupportiveMaterialFieldType.About]; + + this.supportiveMaterialService.queryPublic(lookup) .pipe(takeUntil(this._destroyed)) .subscribe(response => { const blob = new Blob([response.body], { type: 'text/html' }); diff --git a/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts b/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts index d64808040..c5b64e42b 100644 --- a/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts +++ b/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts @@ -28,7 +28,11 @@ export class FaqContentComponent extends BaseComponent implements OnInit { ngOnInit() { this.matomoService.trackPageView('FAQ'); - this.supportiveMaterialService.getMaterial(this.languageService.getCurrentLanguage(), SupportiveMaterialFieldType.Faq) + const lookup = SupportiveMaterialService.DefaultSupportiveMaterialLookup(); + lookup.languageCodes = [this.languageService.getCurrentLanguage()]; + lookup.types = [SupportiveMaterialFieldType.Faq]; + + this.supportiveMaterialService.queryPublic(lookup) .pipe(takeUntil(this._destroyed)) .subscribe(response => { const blob = new Blob([response.body], { type: 'text/html' }); diff --git a/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts b/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts index d1686704d..4e101f9ba 100644 --- a/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts +++ b/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts @@ -36,7 +36,11 @@ export class GlossaryContentComponent extends BaseComponent implements OnInit { this.router.navigate(['/reload'], { skipLocationChange: true }).then(() => this.router.navigate(['/glossary'])); }); - this.supportiveMaterialService.getMaterial(this.languageService.getCurrentLanguage(), SupportiveMaterialFieldType.Glossary) + const lookup = SupportiveMaterialService.DefaultSupportiveMaterialLookup(); + lookup.languageCodes = [this.languageService.getCurrentLanguage()]; + lookup.types = [SupportiveMaterialFieldType.Glossary]; + + this.supportiveMaterialService.queryPublic(lookup) .pipe(takeUntil(this._destroyed)) .subscribe(response => { const blob = new Blob([response.body], { type: 'text/html' }); diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar-footer/terms/terms.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar-footer/terms/terms.component.ts index 23586c4d1..02c540e09 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar-footer/terms/terms.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar-footer/terms/terms.component.ts @@ -33,7 +33,11 @@ export class TermsComponent extends BaseComponent implements OnInit { this.translate.onLangChange.subscribe((event: LangChangeEvent) => { this.router.navigate(['/reload'], { skipLocationChange: true }).then(() => this.router.navigate(['/terms-and-conditions'])); }); - this.supportiveMaterialService.getMaterial(this.languageService.getCurrentLanguage(), SupportiveMaterialFieldType.TermsOfService) + const lookup = SupportiveMaterialService.DefaultSupportiveMaterialLookup(); + lookup.languageCodes = [this.languageService.getCurrentLanguage()]; + lookup.types = [SupportiveMaterialFieldType.TermsOfService]; + + this.supportiveMaterialService.queryPublic(lookup) .pipe(takeUntil(this._destroyed)) .subscribe(response => { const blob = new Blob([response.body], { type: 'text/html' }); diff --git a/dmp-frontend/src/app/ui/supportive-material-editor/supportive-material-editor.component.ts b/dmp-frontend/src/app/ui/supportive-material-editor/supportive-material-editor.component.ts index 8c4901bdb..51b405236 100644 --- a/dmp-frontend/src/app/ui/supportive-material-editor/supportive-material-editor.component.ts +++ b/dmp-frontend/src/app/ui/supportive-material-editor/supportive-material-editor.component.ts @@ -15,6 +15,7 @@ import { HttpClient } from '@angular/common/http'; import { SupportiveMaterialService } from '@app/core/services/supportive-material/supportive-material.service'; import { SupportiveMaterialFieldType } from '@app/core/common/enum/supportive-material-field-type'; import { SupportiveMaterialPersist } from '@app/core/model/supportive-material/supportive-material'; +import { Guid } from '@common/types/guid'; interface VisibleMaterialType{ name: string; @@ -71,6 +72,7 @@ export class SupportiveMaterialEditorComponent extends BaseComponent implements selectedMaterial: VisibleMaterialType; selectedLang: VisibleLangType; + materialId: Guid = null; ngOnInit() { this.selectedMaterial = this.visiblesMaterialsTypes.find(x => x.type == SupportiveMaterialFieldType.Faq); @@ -96,12 +98,21 @@ export class SupportiveMaterialEditorComponent extends BaseComponent implements name: [''], html: [''] }); - this.supportiveMaterialService.getMaterial(this.selectedLang.type, this.selectedMaterial.type).pipe(takeUntil(this._destroyed)).subscribe(data => { - const contentDispositionHeader = data.headers.get('Content-Disposition'); - const filename = contentDispositionHeader.split(';')[1].trim().split('=')[1].replace(/"/g, ''); + // this.supportiveMaterialService.getPublic(this.selectedLang.type, this.selectedMaterial.type).pipe(takeUntil(this._destroyed)).subscribe(data => { + // const contentDispositionHeader = data.headers.get('Content-Disposition'); + // const filename = contentDispositionHeader.split(';')[1].trim().split('=')[1].replace(/"/g, ''); - this.formGroup.get('name').patchValue(filename); - this.loadFile(data.body); + // this.formGroup.get('name').patchValue(filename); + // this.loadFile(data.body); + // }); + const lookup = SupportiveMaterialService.DefaultSupportiveMaterialLookup(); + lookup.types = [this.selectedMaterial.type]; + lookup.languageCodes = [this.selectedLang.type]; + this.supportiveMaterialService.query(lookup).pipe(takeUntil(this._destroyed)).subscribe(data => { + if(data.count == 1){ + this.materialId = data.items[0].id; + this.formGroup.get('html').patchValue(data.items[0].payload); + } }); } @@ -118,29 +129,28 @@ export class SupportiveMaterialEditorComponent extends BaseComponent implements return source; } - loadFile(data: Blob) { - const reader = new FileReader(); - reader.addEventListener('load', () => { - let result = this.parseText(reader.result as string); - //result = result.replace(/class="href" path="/g, 'href="#'); - this.formGroup.get('html').patchValue(result); - }, false); - reader.readAsText(data); - } +// loadFile(data: Blob) { +// const reader = new FileReader(); +// reader.addEventListener('load', () => { +// let result = this.parseText(reader.result as string); +// //result = result.replace(/class="href" path="/g, 'href="#'); +// this.formGroup.get('html').patchValue(result); +// }, false); +// reader.readAsText(data); +// } submit() { let result = this.parseText(this.formGroup.get('html').value); - //result = result.replace(/href="#/g, 'class="href" path="'); this.formGroup.get('html').patchValue(result); - const item = {name: this.formGroup.value['name'], type: this.selectedMaterial.type ,html: this.formGroup.value['html']} as SupportiveMaterialPersist - if(item.name.endsWith("_en.html") && this.selectedLang.type != "en" ){ - item.name = item.name.replace("_en.html", `_${this.selectedLang.type}.html`); - } - + const item = {id: this.materialId, + type: this.selectedMaterial.type, + languageCode: this.selectedLang.type, + payload: this.formGroup.value['html']} as SupportiveMaterialPersist; + this.supportiveMaterialService.persist(item).pipe(takeUntil(this._destroyed)) .subscribe( complete => { - this.onCallbackSuccess(complete); + this.onCallbackSuccess(); }, error => { this.onCallbackError(error); @@ -149,9 +159,9 @@ export class SupportiveMaterialEditorComponent extends BaseComponent implements } -onCallbackSuccess(id?: String): void { +onCallbackSuccess(): void { this.uiNotificationService.snackBarNotification( this.translate.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); - this.router.navigate(['/reload']).then(() => this.router.navigate(['/user-guide-editor'])); + this.router.navigate(['/reload']).then(() => this.router.navigate(['/supportive-material'])); } onCallbackError(error: any) { diff --git a/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts b/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts index fd2f5a08d..6b4f9acf7 100644 --- a/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts +++ b/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts @@ -51,7 +51,11 @@ export class UserGuideContentComponent extends BaseComponent implements OnInit { this.translate.onLangChange.subscribe((event: LangChangeEvent) => { this.router.navigate(['/reload'], { skipLocationChange: true }).then(() => this.router.navigate(['/user-guide'])); }); - this.supportiveMaterialService.getMaterial(this.languageService.getCurrentLanguage(), SupportiveMaterialFieldType.UserGuide) + const lookup = SupportiveMaterialService.DefaultSupportiveMaterialLookup(); + lookup.languageCodes = [this.languageService.getCurrentLanguage()]; + lookup.types = [SupportiveMaterialFieldType.UserGuide]; + + this.supportiveMaterialService.queryPublic(lookup) .pipe(takeUntil(this._destroyed)) .subscribe(response => { const blob = new Blob([response.body], { type: 'text/html' });