From b8c5edf4fbab2eaaf899616e1006703c0bab93a5 Mon Sep 17 00:00:00 2001 From: amentis Date: Thu, 29 Feb 2024 11:46:59 +0200 Subject: [PATCH] separate prefilling sources fixed Value fields --- .../PrefillingSourceDefinitionEntity.java | 11 + ...PrefillingSourceDefinitionFieldEntity.java | 9 - ...SourceDefinitionFixedValueFieldEntity.java | 46 ++++ .../PrefillingSourceDefinitionBuilder.java | 2 + ...refillingSourceDefinitionFieldBuilder.java | 1 - ...ourceDefinitionFixedValueFieldBuilder.java | 60 +++++ ...refillingSourceDefinitionFieldPersist.java | 16 +- ...ourceDefinitionFixedValueFieldPersist.java | 100 ++++++++ .../PrefillingSourceDefinitionPersist.java | 18 +- .../PrefillingSourceDefinition.java | 11 + .../PrefillingSourceDefinitionField.java | 9 - ...illingSourceDefinitionFixedValueField.java | 44 ++++ .../PrefillingSourceService.java | 11 + .../PrefillingSourceServiceImpl.java | 218 +++++++++++++++++- .../PrefillingSourceController.java | 40 ++++ 15 files changed, 559 insertions(+), 37 deletions(-) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionFixedValueFieldEntity.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionFixedValueFieldBuilder.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFixedValueFieldPersist.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinitionFixedValueField.java diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionEntity.java index 9ca6083c7..472f34f20 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionEntity.java @@ -15,6 +15,9 @@ public class PrefillingSourceDefinitionEntity { @XmlElementWrapper(name = "fields") @XmlElement(name = "field") private List fields; + @XmlElementWrapper(name = "fixedValueFields") + @XmlElement(name = "fixedValueField") + private List fixedValueFields; public ExternalFetcherApiSourceConfigurationEntity getSearchConfiguration() { return searchConfiguration; @@ -39,4 +42,12 @@ public class PrefillingSourceDefinitionEntity { public void setFields(List fields) { this.fields = fields; } + + public List getFixedValueFields() { + return fixedValueFields; + } + + public void setFixedValueFields(List fixedValueFields) { + this.fixedValueFields = fixedValueFields; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionFieldEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionFieldEntity.java index f40aeb187..ebdd6d385 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionFieldEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionFieldEntity.java @@ -7,7 +7,6 @@ public class PrefillingSourceDefinitionFieldEntity { private String systemFieldTarget; private String semanticTarget; private String trimRegex; - private String fixedValue; public String getCode() { return code; @@ -45,12 +44,4 @@ public class PrefillingSourceDefinitionFieldEntity { this.trimRegex = trimRegex; } - public String getFixedValue() { - return fixedValue; - } - - @XmlElement(name = "fixedValue") - public void setFixedValue(String fixedValue) { - this.fixedValue = fixedValue; - } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionFixedValueFieldEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionFixedValueFieldEntity.java new file mode 100644 index 000000000..880800596 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/prefillingsource/PrefillingSourceDefinitionFixedValueFieldEntity.java @@ -0,0 +1,46 @@ +package eu.eudat.commons.types.prefillingsource; + +import jakarta.xml.bind.annotation.XmlElement; + +public class PrefillingSourceDefinitionFixedValueFieldEntity { + private String systemFieldTarget; + private String semanticTarget; + private String trimRegex; + private String fixedValue; + + public String getSystemFieldTarget() { + return systemFieldTarget; + } + + @XmlElement(name = "systemFieldTarget") + public void setSystemFieldTarget(String systemFieldTarget) { + this.systemFieldTarget = systemFieldTarget; + } + + public String getSemanticTarget() { + return semanticTarget; + } + + @XmlElement(name = "semanticTarget") + public void setSemanticTarget(String semanticTarget) { + this.semanticTarget = semanticTarget; + } + + public String getTrimRegex() { + return trimRegex; + } + + @XmlElement(name = "trimRegex") + public void setTrimRegex(String trimRegex) { + this.trimRegex = trimRegex; + } + + public String getFixedValue() { + return fixedValue; + } + + @XmlElement(name = "fixedValue") + public void setFixedValue(String fixedValue) { + this.fixedValue = fixedValue; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionBuilder.java index 95ba37811..1c0b7153b 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionBuilder.java @@ -49,11 +49,13 @@ public class PrefillingSourceDefinitionBuilder extends BaseBuilder models = new ArrayList<>(); for (PrefillingSourceDefinitionEntity d : data) { PrefillingSourceDefinition m = new PrefillingSourceDefinition(); if (!fieldsFields.isEmpty() && d.getFields() != null) m.setFields(this.builderFactory.builder(PrefillingSourceDefinitionFieldBuilder.class).authorize(this.authorize).build(fieldsFields, d.getFields())); + if (!fixedValueFieldsFields.isEmpty() && d.getFixedValueFields() != null) m.setFixedValueFields(this.builderFactory.builder(PrefillingSourceDefinitionFixedValueFieldBuilder.class).authorize(this.authorize).build(fixedValueFieldsFields, d.getFixedValueFields())); if (!searchConfigurationFields.isEmpty() && d.getSearchConfiguration() != null) { m.setSearchConfiguration((ExternalFetcherApiSourceConfiguration) this.builderFactory.builder(ExternalFetcherApiSourceConfigurationBuilder.class).authorize(this.authorize).build(searchConfigurationFields, d.getSearchConfiguration())); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionFieldBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionFieldBuilder.java index 0393df566..567dde658 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionFieldBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/prefillingsourcedefinition/PrefillingSourceDefinitionFieldBuilder.java @@ -51,7 +51,6 @@ public class PrefillingSourceDefinitionFieldBuilder extends BaseBuilder { + + private final BuilderFactory builderFactory; + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + @Autowired + public PrefillingSourceDefinitionFixedValueFieldBuilder( + ConventionService conventionService, BuilderFactory builderFactory) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(PrefillingSourceDefinitionFixedValueFieldBuilder.class))); + this.builderFactory = builderFactory; + } + + public PrefillingSourceDefinitionFixedValueFieldBuilder 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 (PrefillingSourceDefinitionFixedValueFieldEntity d : data) { + PrefillingSourceDefinitionFixedValueField m = new PrefillingSourceDefinitionFixedValueField(); + if (fields.hasField(this.asIndexer(PrefillingSourceDefinitionFixedValueField._systemFieldTarget))) m.setSystemFieldTarget(d.getSystemFieldTarget()); + if (fields.hasField(this.asIndexer(PrefillingSourceDefinitionFixedValueField._semanticTarget))) m.setSemanticTarget(d.getSemanticTarget()); + if (fields.hasField(this.asIndexer(PrefillingSourceDefinitionFixedValueField._trimRegex))) m.setTrimRegex(d.getTrimRegex()); + if (fields.hasField(this.asIndexer(PrefillingSourceDefinitionFixedValueField._fixedValue))) m.setFixedValue(d.getFixedValue()); + + 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/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFieldPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFieldPersist.java index 1288ea9dc..d253c6ede 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFieldPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFieldPersist.java @@ -24,8 +24,6 @@ public class PrefillingSourceDefinitionFieldPersist { public final static String _semanticTarget = "semanticTarget"; private String trimRegex; public final static String _trimRegex = "trimRegex"; - private String fixedValue; - public final static String _fixedValue = "fixedValue"; public String getCode() { return code; @@ -59,14 +57,6 @@ public class PrefillingSourceDefinitionFieldPersist { this.trimRegex = trimRegex; } - public String getFixedValue() { - return fixedValue; - } - - public void setFixedValue(String fixedValue) { - this.fixedValue = fixedValue; - } - @Component(PrefillingSourceDefinitionFieldPersist.PrefillingSourceDefinitionFieldPersistValidator.ValidatorName) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) @@ -94,7 +84,11 @@ public class PrefillingSourceDefinitionFieldPersist { return Arrays.asList( this.spec() .must(() -> !this.isEmpty(item.getCode())) - .failOn(PrefillingSourceDefinitionFieldPersist._code).failWith(messageSource.getMessage("Validation_Required", new Object[]{PrefillingSourceDefinitionFieldPersist._code}, LocaleContextHolder.getLocale())) + .failOn(PrefillingSourceDefinitionFieldPersist._code).failWith(messageSource.getMessage("Validation_Required", new Object[]{PrefillingSourceDefinitionFieldPersist._code}, LocaleContextHolder.getLocale())), + this.spec() + .must(() -> !this.isEmpty(item.getSemanticTarget()) || !this.isEmpty(item.getSystemFieldTarget())) + .failOn(PrefillingSourceDefinitionFieldPersist._semanticTarget).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{PrefillingSourceDefinitionFieldPersist._semanticTarget}, LocaleContextHolder.getLocale())) + ); } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFixedValueFieldPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFixedValueFieldPersist.java new file mode 100644 index 000000000..4f6f083f7 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionFixedValueFieldPersist.java @@ -0,0 +1,100 @@ +package eu.eudat.model.persist.prefillingsourcedefinition; + +import eu.eudat.commons.validation.BaseValidator; +import eu.eudat.convention.ConventionService; +import eu.eudat.errorcode.ErrorThesaurusProperties; +import gr.cite.tools.validation.ValidatorFactory; +import gr.cite.tools.validation.specification.Specification; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Scope; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +public class PrefillingSourceDefinitionFixedValueFieldPersist { + + private String systemFieldTarget; + public final static String _systemFieldTarget = "systemFieldTarget"; + private String semanticTarget; + public final static String _semanticTarget = "semanticTarget"; + private String trimRegex; + public final static String _trimRegex = "trimRegex"; + private String fixedValue; + public final static String _fixedValue = "fixedValue"; + + public String getSystemFieldTarget() { + return systemFieldTarget; + } + + public void setSystemFieldTarget(String systemFieldTarget) { + this.systemFieldTarget = systemFieldTarget; + } + + public String getSemanticTarget() { + return semanticTarget; + } + + public void setSemanticTarget(String semanticTarget) { + this.semanticTarget = semanticTarget; + } + + public String getTrimRegex() { + return trimRegex; + } + + public void setTrimRegex(String trimRegex) { + this.trimRegex = trimRegex; + } + + public String getFixedValue() { + return fixedValue; + } + + public void setFixedValue(String fixedValue) { + this.fixedValue = fixedValue; + } + + + @Component(PrefillingSourceDefinitionFixedValueFieldPersist.PrefillingSourceDefinitionFixedValueFieldPersistValidator.ValidatorName) + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public static class PrefillingSourceDefinitionFixedValueFieldPersistValidator extends BaseValidator { + + public static final String ValidatorName = "PrefillingSourceDefinitionFixedValueFieldPersistValidator"; + + private final MessageSource messageSource; + + private final ValidatorFactory validatorFactory; + + protected PrefillingSourceDefinitionFixedValueFieldPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { + super(conventionService, errors); + this.messageSource = messageSource; + this.validatorFactory = validatorFactory; + } + + @Override + protected Class modelClass() { + return PrefillingSourceDefinitionFixedValueFieldPersist.class; + } + + @Override + protected List specifications(PrefillingSourceDefinitionFixedValueFieldPersist item) { + return Arrays.asList( + this.spec() + .must(() -> !this.isEmpty(item.getFixedValue())) + .failOn(PrefillingSourceDefinitionFixedValueFieldPersist._fixedValue).failWith(messageSource.getMessage("Validation_Required", new Object[]{PrefillingSourceDefinitionFixedValueFieldPersist._fixedValue}, LocaleContextHolder.getLocale())), + this.spec() + .iff(() -> !this.isEmpty(item.getFixedValue())) + .must(() -> this.isEmpty(item.getSemanticTarget())) + .failOn(PrefillingSourceDefinitionFixedValueFieldPersist._semanticTarget).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{PrefillingSourceDefinitionFixedValueFieldPersist._semanticTarget}, LocaleContextHolder.getLocale())), + this.spec() + .iff(() -> !this.isEmpty(item.getSemanticTarget())) + .must(() -> this.isEmpty(item.getFixedValue())) + .failOn(PrefillingSourceDefinitionFixedValueFieldPersist._fixedValue).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{PrefillingSourceDefinitionFixedValueFieldPersist._fixedValue}, LocaleContextHolder.getLocale())) + + ); + } + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java index ed6f4c5ee..f6738960a 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/prefillingsourcedefinition/PrefillingSourceDefinitionPersist.java @@ -29,6 +29,9 @@ public class PrefillingSourceDefinitionPersist { private List fields; public static final String _fields = "fields"; + private List fixedValueFields; + public static final String _fixedValueFields = "fixedValueFields"; + public ExternalFetcherApiSourceConfigurationPersist getSearchConfiguration() { return searchConfiguration; } @@ -61,6 +64,14 @@ public class PrefillingSourceDefinitionPersist { this.fields = fields; } + public List getFixedValueFields() { + return fixedValueFields; + } + + public void setFixedValueFields(List fixedValueFields) { + this.fixedValueFields = fixedValueFields; + } + @Component(PrefillingSourceDefinitionPersist.PrefillingSourceDefinitionPersistValidator.ValidatorName) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public static class PrefillingSourceDefinitionPersistValidator extends BaseValidator { @@ -102,7 +113,12 @@ public class PrefillingSourceDefinitionPersist { .iff(() -> !this.isListNullOrEmpty(item.getFields())) .on(PrefillingSourceDefinitionPersist._fields) .over(item.getFields()) - .using((itm) -> this.validatorFactory.validator(PrefillingSourceDefinitionFieldPersist.PrefillingSourceDefinitionFieldPersistValidator.class)) + .using((itm) -> this.validatorFactory.validator(PrefillingSourceDefinitionFieldPersist.PrefillingSourceDefinitionFieldPersistValidator.class)), + this.navSpec() + .iff(() -> !this.isListNullOrEmpty(item.getFixedValueFields())) + .on(PrefillingSourceDefinitionPersist._fixedValueFields) + .over(item.getFixedValueFields()) + .using((itm) -> this.validatorFactory.validator(PrefillingSourceDefinitionFixedValueFieldPersist.PrefillingSourceDefinitionFixedValueFieldPersistValidator.class)) ); } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinition.java b/dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinition.java index 07e99a5ab..451500b53 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinition.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinition.java @@ -15,6 +15,9 @@ public class PrefillingSourceDefinition { private List fields; public final static String _fields = "fields"; + private List fixedValueFields; + public final static String _fixedValueFields = "fixedValueFields"; + public ExternalFetcherApiSourceConfiguration getSearchConfiguration() { return searchConfiguration; } @@ -38,4 +41,12 @@ public class PrefillingSourceDefinition { public void setFields(List fields) { this.fields = fields; } + + public List getFixedValueFields() { + return fixedValueFields; + } + + public void setFixedValueFields(List fixedValueFields) { + this.fixedValueFields = fixedValueFields; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinitionField.java b/dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinitionField.java index 73d95cb39..77da8fb4c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinitionField.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinitionField.java @@ -10,8 +10,6 @@ public class PrefillingSourceDefinitionField { public final static String _semanticTarget = "semanticTarget"; private String trimRegex; public final static String _trimRegex = "trimRegex"; - private String fixedValue; - public final static String _fixedValue = "fixedValue"; public String getCode() { return code; @@ -45,11 +43,4 @@ public class PrefillingSourceDefinitionField { this.trimRegex = trimRegex; } - public String getFixedValue() { - return fixedValue; - } - - public void setFixedValue(String fixedValue) { - this.fixedValue = fixedValue; - } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinitionFixedValueField.java b/dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinitionFixedValueField.java new file mode 100644 index 000000000..c87398dbb --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/prefillingsourcedefinition/PrefillingSourceDefinitionFixedValueField.java @@ -0,0 +1,44 @@ +package eu.eudat.model.prefillingsourcedefinition; + +public class PrefillingSourceDefinitionFixedValueField { + private String systemFieldTarget; + public final static String _systemFieldTarget = "systemFieldTarget"; + private String semanticTarget; + public final static String _semanticTarget = "semanticTarget"; + private String trimRegex; + public final static String _trimRegex = "trimRegex"; + private String fixedValue; + public final static String _fixedValue = "fixedValue"; + + public String getSystemFieldTarget() { + return systemFieldTarget; + } + + public void setSystemFieldTarget(String systemFieldTarget) { + this.systemFieldTarget = systemFieldTarget; + } + + public String getSemanticTarget() { + return semanticTarget; + } + + public void setSemanticTarget(String semanticTarget) { + this.semanticTarget = semanticTarget; + } + + public String getTrimRegex() { + return trimRegex; + } + + public void setTrimRegex(String trimRegex) { + this.trimRegex = trimRegex; + } + + public String getFixedValue() { + return fixedValue; + } + + public void setFixedValue(String fixedValue) { + this.fixedValue = fixedValue; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceService.java b/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceService.java index 510b23015..ace0c720c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceService.java @@ -1,6 +1,9 @@ package eu.eudat.service.prefillingsource; +import eu.eudat.model.Description; import eu.eudat.model.PrefillingSource; +import eu.eudat.model.persist.DescriptionProfilingRequest; +import eu.eudat.model.persist.DescriptionProfilingWithDataRequest; import eu.eudat.model.persist.PrefillingSourcePersist; import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyForbiddenException; @@ -8,8 +11,11 @@ import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.exception.MyValidationException; import gr.cite.tools.fieldset.FieldSet; import jakarta.xml.bind.JAXBException; +import org.xml.sax.SAXException; import javax.management.InvalidApplicationException; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; import java.util.UUID; public interface PrefillingSourceService { @@ -17,4 +23,9 @@ public interface PrefillingSourceService { PrefillingSource persist(PrefillingSourcePersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException; void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException; + + Description getPrefilledDescription(DescriptionProfilingRequest model) throws JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException; + + Description getPrefilledDescriptionUsingData(DescriptionProfilingWithDataRequest model) throws JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException; + } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceServiceImpl.java index a8c36a34e..4d25c5bdb 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/prefillingsource/PrefillingSourceServiceImpl.java @@ -1,25 +1,45 @@ package eu.eudat.service.prefillingsource; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.authorization.Permission; import eu.eudat.commons.XmlHandlingService; import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.types.descriptiontemplate.DefinitionEntity; +import eu.eudat.commons.types.descriptiontemplate.FieldEntity; +import eu.eudat.commons.types.descriptiontemplate.FieldSetEntity; import eu.eudat.commons.types.externalfetcher.*; import eu.eudat.commons.types.prefillingsource.PrefillingSourceDefinitionEntity; import eu.eudat.commons.types.prefillingsource.PrefillingSourceDefinitionFieldEntity; +import eu.eudat.commons.types.prefillingsource.PrefillingSourceDefinitionFixedValueFieldEntity; import eu.eudat.convention.ConventionService; +import eu.eudat.data.DescriptionTemplateEntity; import eu.eudat.data.PrefillingSourceEntity; import eu.eudat.errorcode.ErrorThesaurusProperties; -import eu.eudat.model.PrefillingSource; +import eu.eudat.model.*; +import eu.eudat.model.builder.DescriptionTemplateBuilder; import eu.eudat.model.builder.PrefillingSourceBuilder; import eu.eudat.model.deleter.PrefillingSourceDeleter; +import eu.eudat.model.descriptionproperties.Field; +import eu.eudat.model.descriptionproperties.PropertyDefinition; +import eu.eudat.model.descriptionproperties.PropertyDefinitionFieldSet; +import eu.eudat.model.descriptionproperties.PropertyDefinitionFieldSetItem; +import eu.eudat.model.externalfetcher.ExternalFetcherApiSourceConfiguration; +import eu.eudat.model.persist.DescriptionProfilingRequest; +import eu.eudat.model.persist.DescriptionProfilingWithDataRequest; import eu.eudat.model.persist.PrefillingSourcePersist; import eu.eudat.model.persist.externalfetcher.*; import eu.eudat.model.persist.prefillingsourcedefinition.PrefillingSourceDefinitionFieldPersist; +import eu.eudat.model.persist.prefillingsourcedefinition.PrefillingSourceDefinitionFixedValueFieldPersist; import eu.eudat.model.persist.prefillingsourcedefinition.PrefillingSourceDefinitionPersist; +import eu.eudat.query.PrefillingSourceQuery; +import eu.eudat.service.externalfetcher.ExternalFetcherService; +import eu.eudat.service.externalfetcher.models.ExternalDataResult; 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; @@ -28,6 +48,7 @@ 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 gr.cite.tools.validation.ValidatorFactory; import jakarta.persistence.EntityManager; import jakarta.xml.bind.JAXBException; import org.jetbrains.annotations.NotNull; @@ -35,12 +56,15 @@ import org.slf4j.LoggerFactory; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Service; +import org.xml.sax.SAXException; import javax.management.InvalidApplicationException; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; import java.time.Instant; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.*; @Service public class PrefillingSourceServiceImpl implements PrefillingSourceService { @@ -50,24 +74,30 @@ public class PrefillingSourceServiceImpl implements PrefillingSourceService { private final AuthorizationService authorizationService; private final DeleterFactory deleterFactory; private final BuilderFactory builderFactory; + private final QueryFactory queryFactory; private final ConventionService conventionService; private final MessageSource messageSource; private final XmlHandlingService xmlHandlingService; + private final ExternalFetcherService externalFetcherService; private final ErrorThesaurusProperties errors; + private final ValidatorFactory validatorFactory; public PrefillingSourceServiceImpl( EntityManager entityManager, AuthorizationService authorizationService, DeleterFactory deleterFactory, BuilderFactory builderFactory, - ConventionService conventionService, MessageSource messageSource, - XmlHandlingService xmlHandlingService, ErrorThesaurusProperties errors) { + QueryFactory queryFactory, ConventionService conventionService, MessageSource messageSource, + XmlHandlingService xmlHandlingService, ExternalFetcherService externalFetcherService, ErrorThesaurusProperties errors, ValidatorFactory validatorFactory) { this.entityManager = entityManager; this.authorizationService = authorizationService; this.deleterFactory = deleterFactory; this.builderFactory = builderFactory; + this.queryFactory = queryFactory; this.conventionService = conventionService; this.messageSource = messageSource; this.xmlHandlingService = xmlHandlingService; + this.externalFetcherService = externalFetcherService; this.errors = errors; + this.validatorFactory = validatorFactory; } @@ -114,6 +144,12 @@ public class PrefillingSourceServiceImpl implements PrefillingSourceService { data.getFields().add(this.buildFieldEntity(fieldPersist)); } } + if (!this.conventionService.isListNullOrEmpty(persist.getFixedValueFields())) { + data.setFixedValueFields(new ArrayList<>()); + for (PrefillingSourceDefinitionFixedValueFieldPersist fieldPersist : persist.getFixedValueFields()) { + data.getFixedValueFields().add(this.buildFixedValueFieldEntity(fieldPersist)); + } + } if (persist.getSearchConfiguration() != null ) { data.setSearchConfiguration(this.buildExternalFetcherApiConfigEntity(persist.getSearchConfiguration())); } @@ -130,6 +166,18 @@ public class PrefillingSourceServiceImpl implements PrefillingSourceService { return data; data.setCode(persist.getCode()); + data.setSemanticTarget(persist.getSemanticTarget()); + data.setSystemFieldTarget(persist.getSystemFieldTarget()); + data.setTrimRegex(persist.getTrimRegex()); + + return data; + } + + private @NotNull PrefillingSourceDefinitionFixedValueFieldEntity buildFixedValueFieldEntity(PrefillingSourceDefinitionFixedValueFieldPersist persist) { + PrefillingSourceDefinitionFixedValueFieldEntity data = new PrefillingSourceDefinitionFixedValueFieldEntity(); + if (persist == null) + return data; + data.setSemanticTarget(persist.getSemanticTarget()); data.setSystemFieldTarget(persist.getSystemFieldTarget()); data.setFixedValue(persist.getFixedValue()); @@ -247,4 +295,162 @@ public class PrefillingSourceServiceImpl implements PrefillingSourceService { this.deleterFactory.deleter(PrefillingSourceDeleter.class).deleteAndSaveByIds(List.of(id)); } + + public Description getPrefilledDescription(DescriptionProfilingRequest model) throws JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException { + PrefillingSourceEntity prefillingSourceEntity = this.queryFactory.query(PrefillingSourceQuery.class).ids(UUID.fromString(model.getPrefillId())).first(); + if (prefillingSourceEntity == null){ + return null; + } + + DescriptionProfilingWithDataRequest descriptionProfilingWithDataRequest = new DescriptionProfilingWithDataRequest(); + descriptionProfilingWithDataRequest.setConfigId(model.getConfigId()); + descriptionProfilingWithDataRequest.setProject(model.getProject()); + descriptionProfilingWithDataRequest.setDescriptionTemplateId(model.getDescriptionTemplateId()); +// descriptionProfilingWithDataRequest.setData(prefillingEntity); + validatorFactory.validator(DescriptionProfilingWithDataRequest.DescriptionProfilingWithDataRequestValidator.ValidatorName).validateForce(descriptionProfilingWithDataRequest); + return this.getPrefilledDescriptionUsingData(descriptionProfilingWithDataRequest); + } + + public Description getPrefilledDescriptionUsingData(DescriptionProfilingWithDataRequest model) throws JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException { + + PrefillingSourceEntity prefillingSourceEntity = this.queryFactory.query(PrefillingSourceQuery.class).ids(UUID.fromString(model.getConfigId())).first(); + if (prefillingSourceEntity == null){ + return null; + } + + PrefillingSourceDefinitionEntity prefillingSourceDefinition = this.xmlHandlingService.fromXmlSafe(PrefillingSourceDefinitionEntity.class, prefillingSourceEntity.getDefinition()); + ExternalDataResult data = this.externalFetcherService.getExternalData(List.of(prefillingSourceDefinition.getGetConfiguration()), null, null); + if (data == null || data.getResults() == null){ + return null; + } + DescriptionTemplateEntity descriptionTemplateEntity = this.entityManager.find(DescriptionTemplateEntity.class, model.getDescriptionTemplateId()); + if (descriptionTemplateEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getDescriptionTemplateId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale())); + eu.eudat.commons.types.descriptiontemplate.DefinitionEntity descriptionTemplateDefinition = this.xmlHandlingService.fromXml(eu.eudat.commons.types.descriptiontemplate.DefinitionEntity.class, descriptionTemplateEntity.getDefinition()); + + Description description = new Description(); + description.setDescriptionTemplate(this.builderFactory.builder(DescriptionTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(model.getProject(), descriptionTemplateEntity)); + return mapPrefilledEntityToDescription(description, descriptionTemplateDefinition, prefillingSourceDefinition, prefillingSourceEntity.getLabel(), data.getResults()); + } + + private Description mapPrefilledEntityToDescription(Description description, DefinitionEntity descriptionTemplateDefinition, PrefillingSourceDefinitionEntity prefillingSourceDefinition, String type, List> data){ + for (PrefillingSourceDefinitionFieldEntity field: prefillingSourceDefinition.getFields()) { + String sourceValue = data.get(0).get(field.getCode()); + try { + this.setValueToDescription(description, field, sourceValue, descriptionTemplateDefinition, type); + } + catch (Exception e) { + logger.warn("Couldn't map " + (this.conventionService.isNullOrEmpty(field.getSemanticTarget()) ? field.getSystemFieldTarget() : field.getSemanticTarget())); + } + } + + for (PrefillingSourceDefinitionFixedValueFieldEntity field: prefillingSourceDefinition.getFixedValueFields()) { + try { +// this.setValueToDescription(description, field, field.getFixedValue(), descriptionTemplateDefinition, type); + } + catch (Exception e) { + logger.warn("Couldn't map " + (this.conventionService.isNullOrEmpty(field.getSemanticTarget()) ? field.getSystemFieldTarget() : field.getSemanticTarget())); + } + } + + return description; + } + + private void setValueToDescription(Description description, PrefillingSourceDefinitionFieldEntity field, String value, DefinitionEntity definition, String type) { +// JsonNode valueNode = new ObjectMapper().valueToTree(value); +// String parsedValue = this.getValueAsString(prefillingMapping, valueNode); +// List parsedValues = this.getValueAsStringArray(prefillingMapping, valueNode); + if (field.getSemanticTarget() != null) { + this.applyValueToDescriptionObject(description, field, value, null); + } else { + // zenodo prefilling customizations + if(type.equals("Zenodo")){ + if(field.getSemanticTarget().equals("rda.dataset.distribution.data_access")){ + if(value != null && value.equals("open")){ + List issuedFieldEntities = definition.getAllField().stream().filter(x-> x.getSchematics() != null && x.getSchematics().contains("rda.dataset.issued")).toList(); + if(this.conventionService.isListNullOrEmpty(issuedFieldEntities)){ + String issuedIdNode = issuedFieldEntities.getFirst().getId(); + String issuedValue = description.getProperties().getFieldSets().values().stream().map(PropertyDefinitionFieldSet::getItems).flatMap(List::stream) + .filter(x-> x.getFields() != null && x.getFields().containsKey(issuedIdNode)).map(x-> x.getFields().get(issuedIdNode).getTextValue()).findFirst().orElse(null); //TODO Update with the new logic of property definition + + + List licStartFieldSetsEntities = definition.getAllFieldSets().stream().filter(x-> x.getAllField() != null && x.getAllField().stream().anyMatch(y-> y.getSchematics() != null && y.getSchematics().contains("rda.dataset.distribution.license.start_date"))).toList(); + for (FieldSetEntity licStartFieldSetEntity: licStartFieldSetsEntities) { + List licStartEntities = licStartFieldSetEntity.getAllField().stream().filter(x -> x.getSchematics() != null && x.getSchematics().contains("rda.dataset.distribution.license.start_date")).toList(); + if (!this.conventionService.isListNullOrEmpty(licStartEntities)) { + this.ensureFieldSetEntity(description, licStartFieldSetEntity); + + for (FieldEntity licStartDateNode : licStartEntities) { + description.getProperties().getFieldSets().get(licStartFieldSetEntity.getId()).getItems().add(buildPropertyDefinitionFieldSetItemValue(licStartDateNode, issuedValue, null, type)); + } + } + } + } + } + } + + if (field.getSemanticTarget().equals("rda.dataset.distribution.available_until") && value != null && !value.equals("null")) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd"); + LocalDate date = LocalDate.parse(value, formatter); + date = date.plusYears(20); + value = date.toString(); + } + } + + List fieldSetsEntities = definition.getAllFieldSets().stream().filter(x-> x.getAllField() != null && x.getAllField().stream().anyMatch(y-> y.getSchematics() != null && y.getSchematics().contains(field.getSemanticTarget()))).toList(); + for (FieldSetEntity fieldSetEntity: fieldSetsEntities) { + List fieldEntities = fieldSetEntity.getAllField().stream().filter(x-> x.getSchematics() != null && x.getSchematics().contains(field.getSemanticTarget())).toList(); + if (!this.conventionService.isListNullOrEmpty(fieldEntities)) { + this.ensureFieldSetEntity(description, fieldSetEntity); + + for (FieldEntity fieldEntity : fieldEntities){ + description.getProperties().getFieldSets().get(fieldSetEntity.getId()).getItems().add(buildPropertyDefinitionFieldSetItemValue(fieldEntity, value, null, type)); + } + } + } + } + } + + private void ensureFieldSetEntity(Description description, FieldSetEntity fieldSetEntity){ + if (description.getProperties() == null) description.setProperties(new PropertyDefinition()); + if (description.getProperties().getFieldSets() == null) description.getProperties().setFieldSets(new HashMap<>()); + if (!description.getProperties().getFieldSets().containsKey(fieldSetEntity.getId())) description.getProperties().getFieldSets().put(fieldSetEntity.getId(), new PropertyDefinitionFieldSet()); + if (description.getProperties().getFieldSets().get(fieldSetEntity.getId()).getItems() == null) description.getProperties().getFieldSets().get(fieldSetEntity.getId()).setItems(new ArrayList<>()); + } + + private void applyValueToDescriptionObject(Description description, PrefillingSourceDefinitionFieldEntity field, String parsedValue, List parsedValues) { + switch (field.getSemanticTarget()) { + case Description._description: { + description.setDescription(parsedValue); + } + case Description._label: { + description.setLabel(parsedValue); + } + case Description._descriptionTags: { + if (!parsedValues.isEmpty()) { + for (String tagString : parsedValues) { + if (description.getDescriptionTags() == null) description.setDescriptionTags(new ArrayList<>()); + if (description.getDescriptionTags().stream().anyMatch(x -> x.getTag() != null && x.getTag().getLabel().equals(tagString))) + continue; + + DescriptionTag descriptionTag = new DescriptionTag(); + Tag tag = new Tag(); + tag.setLabel(tagString.trim()); + descriptionTag.setTag(tag); + description.getDescriptionTags().add(descriptionTag); + } + } + } + } + } + + private PropertyDefinitionFieldSetItem buildPropertyDefinitionFieldSetItemValue(FieldEntity fieldEntity, String value, List parsedValues, String type) { + String id = fieldEntity.getId(); + PropertyDefinitionFieldSetItem fieldSetItem = new PropertyDefinitionFieldSetItem(); + fieldSetItem.setFields(new HashMap<>()); + Field field = new Field(); + + fieldSetItem.getFields().put(fieldEntity.getId(), field); + return fieldSetItem; + } + } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/PrefillingSourceController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/PrefillingSourceController.java index 7137398b0..4d0e008c2 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/PrefillingSourceController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/PrefillingSourceController.java @@ -4,9 +4,14 @@ import com.fasterxml.jackson.core.JsonProcessingException; import eu.eudat.audit.AuditableAction; import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.data.PrefillingSourceEntity; +import eu.eudat.model.Description; +import eu.eudat.model.Prefilling; import eu.eudat.model.PrefillingSource; import eu.eudat.model.builder.PrefillingSourceBuilder; +import eu.eudat.model.censorship.DescriptionCensor; import eu.eudat.model.censorship.PrefillingSourceCensor; +import eu.eudat.model.persist.DescriptionProfilingRequest; +import eu.eudat.model.persist.DescriptionProfilingWithDataRequest; import eu.eudat.model.persist.PrefillingSourcePersist; import eu.eudat.model.result.QueryResult; import eu.eudat.query.PrefillingSourceQuery; @@ -31,8 +36,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.web.bind.annotation.*; +import org.xml.sax.SAXException; import javax.management.InvalidApplicationException; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; import java.util.AbstractMap; import java.util.List; import java.util.Map; @@ -136,4 +144,36 @@ public class PrefillingSourceController { this.auditService.track(AuditableAction.PrefillingSource_Delete, "id", id); } + @PostMapping("generate") + @ValidationFilterAnnotation(validator = DescriptionProfilingRequest.DescriptionProfilingRequestValidator.ValidatorName, argumentName = "model") + public Description generate(@RequestBody DescriptionProfilingRequest model) throws MyApplicationException, MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException { + logger.debug(new MapLogEntry("persisting" + Prefilling.class.getSimpleName()).And("model", model)); + + this.censorFactory.censor(DescriptionCensor.class).censor(model.getProject(), null); + + Description item = this.prefillingSourceService.getPrefilledDescription(model); + + this.auditService.track(AuditableAction.Prefilling_Generate, Map.ofEntries( + new AbstractMap.SimpleEntry("model", model) + )); + + return item; + } + + @PostMapping("generate-with-data") + @ValidationFilterAnnotation(validator = DescriptionProfilingWithDataRequest.DescriptionProfilingWithDataRequestValidator.ValidatorName, argumentName = "model") + public Description generateWithData(@RequestBody DescriptionProfilingWithDataRequest model) throws MyApplicationException, MyForbiddenException, MyNotFoundException, JAXBException, ParserConfigurationException, IOException, InstantiationException, IllegalAccessException, SAXException { + logger.debug(new MapLogEntry("persisting" + Prefilling.class.getSimpleName()).And("model", model)); + + this.censorFactory.censor(DescriptionCensor.class).censor(model.getProject(), null); + + Description item = this.prefillingSourceService.getPrefilledDescriptionUsingData(model); + + this.auditService.track(AuditableAction.Prefilling_GenerateWithData, Map.ofEntries( + new AbstractMap.SimpleEntry("model", model) + )); + + return item; + } + }