From 68c56d70a4c873b55fdbb0f045ef915196593552 Mon Sep 17 00:00:00 2001 From: sgiannopoulos Date: Tue, 19 Dec 2023 14:54:17 +0200 Subject: [PATCH 1/7] new logic of validations --- .../commons/validation/BaseValidator.java | 137 +++++++++++-- .../commons/validation/ValidationFailure.java | 24 +++ .../commons/validation/ValidationResult.java | 34 ++++ .../{ModelValidator.java => Validator.java} | 5 +- .../commons/validation/ValidatorFactory.java | 33 ++++ .../NavigationDetailsSpecification.java | 16 ++ ...NavigationDetailsSpecificationBuilder.java | 53 +++++ .../NavigationReferenceSpecification.java | 15 ++ ...vigationReferenceSpecificationBuilder.java | 53 +++++ .../specification/PropertySpecification.java | 15 ++ .../PropertySpecificationBuilder.java | 62 ++++++ .../specification/Specification.java | 6 + .../DescriptionTemplateTypePersist.java | 110 ++++++----- .../GlobalExceptionHandler.java | 185 ++++++++++++++++-- .../ValidatorRequestBodyAdvice.java | 31 +-- .../src/main/resources/messages.properties | 5 +- 16 files changed, 684 insertions(+), 100 deletions(-) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationFailure.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationResult.java rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ModelValidator.java => Validator.java} (56%) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidatorFactory.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationDetailsSpecification.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationDetailsSpecificationBuilder.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationReferenceSpecification.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationReferenceSpecificationBuilder.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/PropertySpecification.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/PropertySpecificationBuilder.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/Specification.java diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java index 9f1773f23..1d8644200 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java @@ -1,47 +1,150 @@ package eu.eudat.commons.validation; +import eu.eudat.commons.validation.specification.*; +import eu.eudat.convention.ConventionService; import eu.eudat.errorcode.ErrorThesaurusProperties; import gr.cite.tools.exception.MyValidationException; import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.Errors; import org.springframework.validation.FieldError; +import org.springframework.validation.ValidationUtils; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.text.MessageFormat; +import java.util.*; -public abstract class BaseValidator implements ModelValidator { - private BeanPropertyBindingResult result; +public abstract class BaseValidator implements Validator { + private BeanPropertyBindingResult bindingResult; + protected final ConventionService conventionService; protected final ErrorThesaurusProperties errors; - protected BaseValidator(ErrorThesaurusProperties errors) { + protected BaseValidator(ConventionService conventionService, ErrorThesaurusProperties errors) { + this.conventionService = conventionService; this.errors = errors; } + protected abstract Class modelClass(); + + protected abstract List specifications(T item); + + @Override + public boolean supports(Class clazz) { + return clazz == null ? false : this.modelClass().equals(clazz); + } + + @Override + public void validate(Object obj, Errors e) { + if (obj == null) return; + T item = this.modelClass().cast(obj); + List specifications = this.specifications(item); + if (specifications == null) return;; + List propertySpecifications = specifications.stream().filter(x-> x instanceof PropertySpecification).map(x-> (PropertySpecification)x).toList(); + for (PropertySpecification propertySpecification : propertySpecifications){ + if ((propertySpecification.getPrecondition() == null || propertySpecification.getPrecondition().get()) && + (propertySpecification.getSpecification() == null || !propertySpecification.getSpecification().get()) + ){ + e.rejectValue(propertySpecification.getErrorKey(), propertySpecification.getErrorCode(), propertySpecification.getErrorMessage()); + } + } + + List navigationReferenceSpecifications = specifications.stream().filter(x-> x instanceof NavigationReferenceSpecification).map(x-> (NavigationReferenceSpecification)x).toList(); + for (NavigationReferenceSpecification navigationReferenceSpecification : navigationReferenceSpecifications){ + if (navigationReferenceSpecification.getReference() != null && (navigationReferenceSpecification.getPrecondition() == null || navigationReferenceSpecification.getPrecondition().get())){ + try { + e.pushNestedPath(navigationReferenceSpecification.getKey()); + ValidationUtils.invokeValidator(navigationReferenceSpecification.getValidator().get(), navigationReferenceSpecification.getReference(), e); + } finally { + e.popNestedPath(); + } + } + } + + List navigationDetailsSpecifications = specifications.stream().filter(x-> x instanceof NavigationDetailsSpecification).map(x-> (NavigationDetailsSpecification)x).toList(); + for (NavigationDetailsSpecification navigationDetailsSpecification : navigationDetailsSpecifications){ + if (navigationDetailsSpecification.getDetails() != null && (navigationDetailsSpecification.getPrecondition() == null || navigationDetailsSpecification.getPrecondition().get())){ + + for (int i = 0; i < navigationDetailsSpecification.getDetails().size(); i++) { + try { + e.pushNestedPath(MessageFormat.format("{0}[{1}]", navigationDetailsSpecification.getKey(), i)); + ValidationUtils.invokeValidator(navigationDetailsSpecification.getValidator().get(), navigationDetailsSpecification.getDetails().get(i), e); + } finally { + e.popNestedPath(); + } + } + } + } + } + @Override public void validate(Object target){ - this.result = new org.springframework.validation.BeanPropertyBindingResult(target, target.getClass().getName()); - this.validate(target, this.result); + this.bindingResult = new org.springframework.validation.BeanPropertyBindingResult(target, target.getClass().getName()); + this.validate(target, this.bindingResult); } @Override public void validateForce(Object target) { this.validate(target); - - if (this.result != null && result.hasErrors()){ - List>> errorsMap = new ArrayList<>(); - for (FieldError fieldError : result.getFieldErrors()){ - errorsMap.add(new AbstractMap.SimpleEntry<>(fieldError.getField(), List.of(fieldError.getDefaultMessage()))); - } + ValidationResult result = result(); + if (!result.isValid()){ + List>> errorsMap = this.flattenValidationResult(); throw new MyValidationException(this.errors.getModelValidation().getCode(), errorsMap); } } + + protected List>> flattenValidationResult() { + ValidationResult result = result(); + List>> errorsMap = new ArrayList<>(); + for (ValidationFailure fieldError : result.getErrors()){ + Map.Entry> entry = errorsMap.stream().filter(x-> Objects.equals(x.getKey(), fieldError.getErrorKey())).findFirst().orElse(null); + if (entry == null) { + entry = new AbstractMap.SimpleEntry<>(fieldError.getErrorKey(), new ArrayList<>()); + errorsMap.add(entry); + } + entry.getValue().add(fieldError.getErrorMessage()); + } + + return errorsMap; + } + + protected PropertySpecificationBuilder spec() { + return new PropertySpecificationBuilder(); + } + + protected NavigationReferenceSpecificationBuilder refSpec() { + return new NavigationReferenceSpecificationBuilder(); + } + + protected NavigationDetailsSpecificationBuilder navSpec() + { + return new NavigationDetailsSpecificationBuilder(); + } @Override - public Errors result() { - return this.result; + public ValidationResult result() { + ValidationResult validationResult = new ValidationResult(); + if (this.bindingResult != null && bindingResult.hasErrors()){ + for (FieldError fieldError : bindingResult.getFieldErrors()){ + validationResult.add(new ValidationFailure(fieldError.getField(), fieldError.getDefaultMessage())); + } + } + return validationResult; + } + + + + protected Boolean isValidGuid(UUID guid) { + return this.conventionService.isValidGuid(guid); + } + + protected Boolean isValidHash(String hash) { + return this.conventionService.isValidHash(hash); + } + + protected Boolean isEmpty(String value) { + return this.conventionService.isNullOrEmpty(value); + } + protected Boolean lessEqual(String value, int size) { + return value.length() <= size; } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationFailure.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationFailure.java new file mode 100644 index 000000000..9d20f56cb --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationFailure.java @@ -0,0 +1,24 @@ +package eu.eudat.commons.validation; + +public class ValidationFailure { + public String errorKey; + + public String errorMessage; + + public ValidationFailure(String errorMessage) { + this.errorMessage = errorMessage; + } + + public ValidationFailure(String errorKey, String errorMessage) { + this.errorKey = errorKey; + this.errorMessage = errorMessage; + } + + public String getErrorKey() { + return errorKey; + } + + public String getErrorMessage() { + return errorMessage; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationResult.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationResult.java new file mode 100644 index 000000000..a659d175f --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationResult.java @@ -0,0 +1,34 @@ +package eu.eudat.commons.validation; + +import java.util.ArrayList; +import java.util.List; + +public class ValidationResult { + private final List errors; + + public ValidationResult() { + this.errors = new ArrayList<>(); + } + + public Boolean isValid() { + return this.errors.isEmpty(); + } + public ValidationResult add(ValidationFailure failure) { + if (failure != null) { + errors.add(failure); + } + return this; + } + + public ValidationResult addAll(List failures) { + if (failures != null) { + errors.addAll(failures); + } + return this; + } + + public List getErrors() { + return errors; + } +} + diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ModelValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/Validator.java similarity index 56% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/ModelValidator.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/Validator.java index 9935d4618..a3db41f5b 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ModelValidator.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/Validator.java @@ -1,10 +1,9 @@ package eu.eudat.commons.validation; import org.springframework.validation.Errors; -import org.springframework.validation.Validator; -public interface ModelValidator extends Validator { +public interface Validator extends org.springframework.validation.Validator { void validate(Object target); void validateForce(Object target); - Errors result(); + ValidationResult result(); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidatorFactory.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidatorFactory.java new file mode 100644 index 000000000..9c3e844b7 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidatorFactory.java @@ -0,0 +1,33 @@ +package eu.eudat.commons.validation; + +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; + +@Service +public class ValidatorFactory { + + private final ApplicationContext applicationContext; + + public ValidatorFactory(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + public T validator(Class type){ + + T item = this.applicationContext.getBean(type); + + if (item == null || !(item instanceof Validator)) throw new RuntimeException("unrecognized validator " + type.getSimpleName()); + + return item; + } + + public Validator validator(String validtor){ + + Validator item = this.applicationContext.getBean(validtor, Validator.class); + + if (item == null || !(item instanceof Validator)) throw new RuntimeException("unrecognized validator " + validtor); + + return item; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationDetailsSpecification.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationDetailsSpecification.java new file mode 100644 index 000000000..9630799fb --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationDetailsSpecification.java @@ -0,0 +1,16 @@ +package eu.eudat.commons.validation.specification; + +import eu.eudat.commons.validation.Validator; + +import java.util.List; +import java.util.function.Supplier; + +public interface NavigationDetailsSpecification extends Specification { + Supplier getPrecondition(); + + String getKey(); + + List getDetails(); + + Supplier getValidator(); +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationDetailsSpecificationBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationDetailsSpecificationBuilder.java new file mode 100644 index 000000000..1e9be5f18 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationDetailsSpecificationBuilder.java @@ -0,0 +1,53 @@ +package eu.eudat.commons.validation.specification; + +import eu.eudat.commons.validation.Validator; + +import java.util.List; +import java.util.function.Supplier; + +public class NavigationDetailsSpecificationBuilder implements NavigationDetailsSpecification { + private Supplier precondition; + private String key; + private List details; + private Supplier validator; + + public NavigationDetailsSpecificationBuilder iff(Supplier value){ + this.precondition = value; + return this; + } + + public NavigationDetailsSpecificationBuilder on(String value){ + this.key = value; + return this; + } + + public NavigationDetailsSpecificationBuilder over(List value){ + this.details = value; + return this; + } + + public NavigationDetailsSpecificationBuilder using(Supplier value){ + this.validator = value; + return this; + } + + @Override + public Supplier getPrecondition() { + return precondition; + } + + @Override + public String getKey() { + return key; + } + + @Override + public List getDetails() { + return details; + } + + @Override + public Supplier getValidator() { + return validator; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationReferenceSpecification.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationReferenceSpecification.java new file mode 100644 index 000000000..0ef62c71a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationReferenceSpecification.java @@ -0,0 +1,15 @@ +package eu.eudat.commons.validation.specification; + +import eu.eudat.commons.validation.Validator; + +import java.util.function.Supplier; + +public interface NavigationReferenceSpecification extends Specification{ + Supplier getPrecondition(); + + String getKey(); + + Object getReference(); + + Supplier getValidator(); +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationReferenceSpecificationBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationReferenceSpecificationBuilder.java new file mode 100644 index 000000000..3f3465226 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/NavigationReferenceSpecificationBuilder.java @@ -0,0 +1,53 @@ +package eu.eudat.commons.validation.specification; + +import eu.eudat.commons.validation.Validator; + +import java.util.function.Supplier; + +public class NavigationReferenceSpecificationBuilder implements NavigationReferenceSpecification { + private Supplier precondition; + private String key; + private Object reference; + private Supplier validator; + + public NavigationReferenceSpecificationBuilder iff(Supplier value){ + this.precondition = value; + return this; + } + + public NavigationReferenceSpecificationBuilder on(String value){ + this.key = value; + return this; + } + + public NavigationReferenceSpecificationBuilder over(Object value){ + this.reference = value; + return this; + } + + public NavigationReferenceSpecificationBuilder using(Supplier value){ + this.validator = value; + return this; + } + + @Override + public Supplier getPrecondition() { + return precondition; + } + + @Override + public String getKey() { + return key; + } + + @Override + public Object getReference() { + return reference; + } + + @Override + public Supplier getValidator() { + return validator; + } +} + diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/PropertySpecification.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/PropertySpecification.java new file mode 100644 index 000000000..12d317d68 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/PropertySpecification.java @@ -0,0 +1,15 @@ +package eu.eudat.commons.validation.specification; + +import java.util.function.Supplier; + +public interface PropertySpecification extends Specification { + + Supplier getPrecondition(); + + Supplier getSpecification(); + + String getErrorKey(); + + String getErrorMessage(); + String getErrorCode(); +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/PropertySpecificationBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/PropertySpecificationBuilder.java new file mode 100644 index 000000000..9851d65c4 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/PropertySpecificationBuilder.java @@ -0,0 +1,62 @@ +package eu.eudat.commons.validation.specification; + +import java.util.function.Supplier; + +public class PropertySpecificationBuilder implements PropertySpecification{ + private Supplier precondition; + private Supplier specification; + private String errorKey; + private String errorMessage; + private String errorCode = "validationerror"; + + public PropertySpecificationBuilder iff(Supplier value){ + this.precondition = value; + return this; + } + + public PropertySpecificationBuilder must(Supplier value){ + this.specification = value; + return this; + } + + public PropertySpecificationBuilder failOn(String value){ + this.errorKey = value; + return this; + } + + public PropertySpecificationBuilder failWith(String value){ + this.errorMessage = value; + return this; + } + + public PropertySpecificationBuilder failWithCode(String value){ + this.errorCode = value; + return this; + } + + @Override + public Supplier getPrecondition() { + return precondition; + } + + @Override + public Supplier getSpecification() { + return specification; + } + + @Override + public String getErrorKey() { + return errorKey; + } + + @Override + public String getErrorMessage() { + return errorMessage; + } + + @Override + public String getErrorCode() { + return errorCode; + } +} + diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/Specification.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/Specification.java new file mode 100644 index 000000000..de64a65f1 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/specification/Specification.java @@ -0,0 +1,6 @@ +package eu.eudat.commons.validation.specification; + +import java.util.function.Supplier; + +public interface Specification { +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java index 54e8f7902..59b9bb274 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java @@ -2,25 +2,26 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.DescriptionTemplateTypeStatus; -import eu.eudat.commons.validation.BaseValidator; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.*; +import eu.eudat.commons.validation.specification.Specification; +import eu.eudat.convention.ConventionService; import eu.eudat.data.DescriptionTemplateTypeEntity; import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.model.Description; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import org.springframework.beans.factory.annotation.Autowired; +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 org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; -import org.springframework.validation.Validator; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.UUID; @@ -30,19 +31,29 @@ public class DescriptionTemplateTypePersist { @ValidId(message = "{validation.invalidid}") private UUID id; + public final static String _id = "id"; + @NotNull(message = "{validation.empty}") @NotEmpty(message = "{validation.empty}") @Size(max = DescriptionTemplateTypeEntity._nameLength, message = "{validation.largerthanmax}") private String name = null; + public final static String _name = "name"; + private String hash; + public final static String _hash = "hash"; + @ValidEnum(message = "{validation.empty}") private DescriptionTemplateTypeStatus status; private List nested; + public final static String _nested = "nested"; + private DescriptionTemplateTypePersist obj; + + public final static String _obj = "obj"; public UUID getId() { return id; @@ -93,62 +104,53 @@ public class DescriptionTemplateTypePersist { } @Component(DescriptionTemplateTypePersistValidator.ValidatorName) - public static class DescriptionTemplateTypePersistValidator extends BaseValidator { - - @Autowired - private DescriptionTemplateTypePersistValidator1 descriptionTemplateTypePersistValidator; + @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public static class DescriptionTemplateTypePersistValidator extends BaseValidator { public static final String ValidatorName = "DescriptionTemplateTypePersistValidator"; + private final ValidatorFactory validatorFactory; + private final MessageSource messageSource; - public DescriptionTemplateTypePersistValidator(MessageSource messageSource, ErrorThesaurusProperties errors) { - super(errors); + public DescriptionTemplateTypePersistValidator(MessageSource messageSource, ValidatorFactory validatorFactory, ConventionService conventionService, ErrorThesaurusProperties errors) { + super(conventionService, errors); this.messageSource = messageSource; + this.validatorFactory = validatorFactory; } - public boolean supports(Class clazz) { - return DescriptionTemplateTypePersist.class.equals(clazz); + @Override + protected Class modelClass() { + return DescriptionTemplateTypePersist.class; } - public void validate(Object obj, Errors e) { - e.rejectValue("name", "negativevalue", messageSource.getMessage("General_ItemNotFound", new Object[]{"aaa", Description.class.getSimpleName()}, LocaleContextHolder.getLocale())); - DescriptionTemplateTypePersist p = (DescriptionTemplateTypePersist) obj; - try { - e.pushNestedPath("obj"); - ValidationUtils.invokeValidator(descriptionTemplateTypePersistValidator, p.getObj(), e); - } finally { - e.popNestedPath(); - } - - - for (int i = 0; i < p.getNested().size(); i++) { - try { - e.pushNestedPath("nested["+i+"]"); - ValidationUtils.invokeValidator(descriptionTemplateTypePersistValidator, p.getObj(), e); - } finally { - e.popNestedPath(); - } - } - } - } - - @Component(DescriptionTemplateTypePersistValidator1.ValidatorName) - public static class DescriptionTemplateTypePersistValidator1 extends BaseValidator { - - public static final String ValidatorName = "DescriptionTemplateTypePersistValidator1"; - private final MessageSource messageSource; - - public DescriptionTemplateTypePersistValidator1(MessageSource messageSource, ErrorThesaurusProperties errors) { - super(errors); - this.messageSource = messageSource; - } - - public boolean supports(Class clazz) { - return DescriptionTemplateTypePersist.class.equals(clazz); - } - - public void validate(Object obj, Errors e) { - e.rejectValue("name", "negativevalue", messageSource.getMessage("General_ItemNotFound", new Object[]{"aaa", Description.class.getSimpleName()}, LocaleContextHolder.getLocale())); - + @Override + protected List specifications(DescriptionTemplateTypePersist item) { + return Arrays.asList( + this.spec() + .iff(() -> this.isValidGuid(item.getId())) + .must(() -> this.isValidHash(item.getHash())) + .failOn(DescriptionTemplateTypePersist._hash).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionTemplateTypePersist._hash}, LocaleContextHolder.getLocale())), + this.spec() + .iff(() -> !this.isValidGuid(item.getId())) + .must(() -> !this.isValidHash(item.getHash())) + .failOn(DescriptionTemplateTypePersist._hash).failWith(messageSource.getMessage("Validation_OverPosting", new Object[]{}, LocaleContextHolder.getLocale())), + this.spec() + .must(() -> !this.isEmpty(item.getName())) + .failOn(DescriptionTemplateTypePersist._name).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionTemplateTypePersist._name}, LocaleContextHolder.getLocale())), + this.spec() + .iff(() -> !this.isEmpty(item.getName())) + .must(() -> this.lessEqual(item.getName(), DescriptionTemplateTypeEntity._nameLength)) + .failOn(DescriptionTemplateTypePersist._name).failWith(messageSource.getMessage("Validation_MaxLength", new Object[]{DescriptionTemplateTypePersist._name}, LocaleContextHolder.getLocale())), + this.refSpec() + .iff(() -> item.getObj() != null) + .on(DescriptionTemplateTypePersist._obj) + .over(item.getObj()) + .using(() -> this.validatorFactory.validator(DescriptionTemplateTypePersistValidator.class)), + this.navSpec() + .iff(() -> item.getNested() != null) + .on(DescriptionTemplateTypePersist._nested) + .over(item.getNested()) + .using(() -> this.validatorFactory.validator(DescriptionTemplateTypePersistValidator.class)) + ); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/controllerhandler/GlobalExceptionHandler.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/controllerhandler/GlobalExceptionHandler.java index 7223a7c57..a28826f3a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/controllerhandler/GlobalExceptionHandler.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/controllerhandler/GlobalExceptionHandler.java @@ -1,30 +1,191 @@ package eu.eudat.controllers.controllerhandler; -import eu.eudat.errorcode.ErrorThesaurusProperties; -import gr.cite.tools.exception.MyValidationException; +import eu.eudat.commons.JsonHandlingService; +import gr.cite.tools.exception.*; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.context.request.WebRequest; +import java.text.MessageFormat; +import java.util.Map; + @RestControllerAdvice @ControllerAdvice public class GlobalExceptionHandler { + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(GlobalExceptionHandler.class)); + + private final JsonHandlingService jsonHandlingService; - private final ErrorThesaurusProperties errors; - - public GlobalExceptionHandler(ErrorThesaurusProperties errors) { - this.errors = errors; + public GlobalExceptionHandler(JsonHandlingService jsonHandlingService) { + this.jsonHandlingService = jsonHandlingService; } + @ExceptionHandler(Exception.class) - public ResponseEntity handleUnexpectedErrors(Exception e, WebRequest request) throws Exception { - if (e instanceof MyValidationException argumentNotValidException) { - return new ResponseEntity<>(argumentNotValidException.getErrors(), HttpStatus.BAD_REQUEST); + public ResponseEntity handleUnexpectedErrors(Exception exception, WebRequest request) throws Exception { + HandledException handled = this.handleException(exception, request); + this.log(handled.getLevel(), exception, MessageFormat.format("returning code {0} and payload {1}", handled.getStatusCode(), handled.getMessage())); + return new ResponseEntity<>(handled.getMessage(), handled.getStatusCode()); + } + + public void log(System.Logger.Level level, Exception e, String message) { + if (level != null) { + switch (level) { + case TRACE: + logger.trace(message, e); + break; + case DEBUG: + logger.debug(message, e); + break; + case INFO: + logger.info(message, e); + break; + case WARNING: + logger.warn(message, e); + break; + case ERROR: + logger.error(message, e); + break; + } } - else { - throw e; + } + + public HandledException handleException(Exception exception, WebRequest request) throws Exception { + HttpStatus statusCode; + Map result; + System.Logger.Level logLevel; + + switch (exception){ + case MyNotFoundException myNotFoundException -> { + logLevel = System.Logger.Level.DEBUG; + statusCode = HttpStatus.NOT_FOUND; + int code = myNotFoundException.getCode(); + if (code > 0) { + result = Map.ofEntries( + Map.entry("code", code), + Map.entry("error", myNotFoundException.getMessage()) + ); + } + else { + result = Map.ofEntries( + Map.entry("error", myNotFoundException.getMessage()) + ); + } + } + case MyUnauthorizedException myUnauthorizedException -> { + logLevel = System.Logger.Level.DEBUG; + statusCode = HttpStatus.UNAUTHORIZED; + int code = myUnauthorizedException.getCode(); + if (code > 0) { + result = Map.ofEntries( + Map.entry("code", code), + Map.entry("error", myUnauthorizedException.getMessage()) + ); + } + else { + result = Map.ofEntries( + Map.entry("error", myUnauthorizedException.getMessage()) + ); + } + } + case MyForbiddenException myForbiddenException -> { + logLevel = System.Logger.Level.DEBUG; + statusCode = HttpStatus.FORBIDDEN; + int code = myForbiddenException.getCode(); + if (code > 0) { + result = Map.ofEntries( + Map.entry("code", code), + Map.entry("error", myForbiddenException.getMessage()) + ); + } + else { + result = Map.ofEntries( + Map.entry("error", myForbiddenException.getMessage()) + ); + } + } + case MyValidationException myValidationException -> { + logLevel = System.Logger.Level.DEBUG; + statusCode = HttpStatus.BAD_REQUEST; + int code = myValidationException.getCode(); + if (code > 0) { + result = Map.ofEntries( + Map.entry("code", code), + Map.entry("error", myValidationException.getMessage()), + Map.entry("message", myValidationException.getErrors()) + ); + } + else { + result = Map.ofEntries( + Map.entry("error", myValidationException.getMessage()), + Map.entry("message", myValidationException.getErrors()) + ); + } + } + case MyApplicationException myApplicationException -> { + logLevel = System.Logger.Level.ERROR; + statusCode = HttpStatus.INTERNAL_SERVER_ERROR; + int code = myApplicationException.getCode(); + if (code > 0) { + result = Map.ofEntries( + Map.entry("code", code), + Map.entry("error", myApplicationException.getMessage()) + ); + } + else { + result = Map.ofEntries( + Map.entry("error", myApplicationException.getMessage()) + ); + } + } + default -> { + logLevel = System.Logger.Level.ERROR; + statusCode = HttpStatus.INTERNAL_SERVER_ERROR; + result = Map.ofEntries( + Map.entry("error", "System error") + ); + } + }; + String serialization = this.jsonHandlingService.toJsonSafe(result); + return new HandledException(statusCode, serialization, logLevel); + } + + public static class HandledException{ + public HttpStatus statusCode; + public String message; + public System.Logger.Level level; + + public HandledException(HttpStatus statusCode, String message, System.Logger.Level level) { + this.statusCode = statusCode; + this.message = message; + this.level = level; } - } + public HttpStatus getStatusCode() { + return statusCode; + } + + public void setStatusCode(HttpStatus statusCode) { + this.statusCode = statusCode; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public System.Logger.Level getLevel() { + return level; + } + + public void setLevel(System.Logger.Level level) { + this.level = level; + } + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/controllerhandler/ValidatorRequestBodyAdvice.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/controllerhandler/ValidatorRequestBodyAdvice.java index f5a589b33..b8be7a9e9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/controllerhandler/ValidatorRequestBodyAdvice.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/controllerhandler/ValidatorRequestBodyAdvice.java @@ -1,10 +1,9 @@ package eu.eudat.controllers.controllerhandler; -import eu.eudat.commons.validation.BaseValidator; +import eu.eudat.commons.validation.Validator; +import eu.eudat.commons.validation.ValidatorFactory; import eu.eudat.commons.validation.ValidationFilterAnnotation; -import eu.eudat.logic.services.ApiContext; import gr.cite.tools.exception.MyApplicationException; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.MethodParameter; import org.springframework.http.HttpInputMessage; import org.springframework.http.converter.HttpMessageConverter; @@ -19,21 +18,27 @@ import java.util.Objects; @ControllerAdvice @RestControllerAdvice public class ValidatorRequestBodyAdvice implements RequestBodyAdvice { - @Autowired - private ApiContext apiContext; + private final ValidatorFactory validatorFactory; + + public ValidatorRequestBodyAdvice(ValidatorFactory validatorFactory) { + this.validatorFactory = validatorFactory; + } @Override public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class> converterType) { if (parameter.getMethod() != null) { - ValidationFilterAnnotation annotation = parameter.getMethod().getAnnotation((ValidationFilterAnnotation.class)); + ValidationFilterAnnotation[] annotations = parameter.getMethod().getAnnotationsByType((ValidationFilterAnnotation.class)); - if (annotation == null || !Objects.equals(parameter.getParameterName(), annotation.argumentName())) return body; + if (annotations == null) return body; + for (ValidationFilterAnnotation annotation : annotations){ + if (!Objects.equals(parameter.getParameterName(), annotation.argumentName())) continue; - BaseValidator validator = this.apiContext.getOperationsContext().getApplicationContext().getBean(annotation.validator(), BaseValidator.class); - if (validator == null) throw new MyApplicationException("validator not provided"); - - validator.validateForce(body); + Validator validator = validatorFactory.validator(annotation.validator()); + if (validator == null) throw new MyApplicationException("validator not provided"); + + validator.validateForce(body); + } } return body; } @@ -44,8 +49,8 @@ public class ValidatorRequestBodyAdvice implements RequestBodyAdvice { } @Override - public boolean supports(MethodParameter methodParameter, Type targetType, Class> converterType) { - return true; + public boolean supports(MethodParameter parameter, Type targetType, Class> converterType) { + return parameter.getMethod() != null && parameter.getMethod().isAnnotationPresent((ValidationFilterAnnotation.class)); } @Override diff --git a/dmp-backend/web/src/main/resources/messages.properties b/dmp-backend/web/src/main/resources/messages.properties index 7547f0630..5ff4a0394 100644 --- a/dmp-backend/web/src/main/resources/messages.properties +++ b/dmp-backend/web/src/main/resources/messages.properties @@ -16,4 +16,7 @@ validation.lowerthanmin=Value must be larger than {value} validation.largerthanmax=Value must be less than {value} validation.invalidid=Not valid id General_ItemNotFound=Item {0} of type {1} not found -Validation_Required={0} is required \ No newline at end of file +Validation_Required={0} is required +Validation_OverPosting=Too much info +Validation_MaxLength={0} too long +Validation_UnexpectedValue=Unexpected value in field {0} \ No newline at end of file From 4fa4cdc6712d20eee94642b827009a0cf09ebf0d Mon Sep 17 00:00:00 2001 From: sgiannopoulos Date: Tue, 19 Dec 2023 15:11:22 +0200 Subject: [PATCH 2/7] DescriptionTemplateTypePersist remove old validators --- .../DescriptionTemplateTypePersist.java | 67 ++++++------------- 1 file changed, 19 insertions(+), 48 deletions(-) diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java index 59b9bb274..94c19c901 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java @@ -8,7 +8,6 @@ import eu.eudat.commons.validation.specification.Specification; import eu.eudat.convention.ConventionService; import eu.eudat.data.DescriptionTemplateTypeEntity; import eu.eudat.errorcode.ErrorThesaurusProperties; -import eu.eudat.model.Description; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; @@ -17,25 +16,16 @@ import org.springframework.context.MessageSource; import org.springframework.context.annotation.Scope; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Component; -import org.springframework.validation.Errors; -import org.springframework.validation.ValidationUtils; - -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; -@FieldNotNullIfOtherSet(message = "{validation.hashempty}") public class DescriptionTemplateTypePersist { - @ValidId(message = "{validation.invalidid}") private UUID id; public final static String _id = "id"; - @NotNull(message = "{validation.empty}") - @NotEmpty(message = "{validation.empty}") - @Size(max = DescriptionTemplateTypeEntity._nameLength, message = "{validation.largerthanmax}") private String name = null; public final static String _name = "name"; @@ -44,16 +34,15 @@ public class DescriptionTemplateTypePersist { public final static String _hash = "hash"; - @ValidEnum(message = "{validation.empty}") private DescriptionTemplateTypeStatus status; - private List nested; - - public final static String _nested = "nested"; - - private DescriptionTemplateTypePersist obj; - - public final static String _obj = "obj"; +// private List nested; +// +// public final static String _nested = "nested"; +// +// private DescriptionTemplateTypePersist obj; +// +// public final static String _obj = "obj"; public UUID getId() { return id; @@ -87,34 +76,16 @@ public class DescriptionTemplateTypePersist { this.status = status; } - public List getNested() { - return nested; - } - - public void setNested(List nested) { - this.nested = nested; - } - - public DescriptionTemplateTypePersist getObj() { - return obj; - } - - public void setObj(DescriptionTemplateTypePersist obj) { - this.obj = obj; - } - @Component(DescriptionTemplateTypePersistValidator.ValidatorName) @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public static class DescriptionTemplateTypePersistValidator extends BaseValidator { public static final String ValidatorName = "DescriptionTemplateTypePersistValidator"; - private final ValidatorFactory validatorFactory; private final MessageSource messageSource; - public DescriptionTemplateTypePersistValidator(MessageSource messageSource, ValidatorFactory validatorFactory, ConventionService conventionService, ErrorThesaurusProperties errors) { + public DescriptionTemplateTypePersistValidator(MessageSource messageSource, ConventionService conventionService, ErrorThesaurusProperties errors) { super(conventionService, errors); this.messageSource = messageSource; - this.validatorFactory = validatorFactory; } @Override @@ -139,17 +110,17 @@ public class DescriptionTemplateTypePersist { this.spec() .iff(() -> !this.isEmpty(item.getName())) .must(() -> this.lessEqual(item.getName(), DescriptionTemplateTypeEntity._nameLength)) - .failOn(DescriptionTemplateTypePersist._name).failWith(messageSource.getMessage("Validation_MaxLength", new Object[]{DescriptionTemplateTypePersist._name}, LocaleContextHolder.getLocale())), - this.refSpec() - .iff(() -> item.getObj() != null) - .on(DescriptionTemplateTypePersist._obj) - .over(item.getObj()) - .using(() -> this.validatorFactory.validator(DescriptionTemplateTypePersistValidator.class)), - this.navSpec() - .iff(() -> item.getNested() != null) - .on(DescriptionTemplateTypePersist._nested) - .over(item.getNested()) - .using(() -> this.validatorFactory.validator(DescriptionTemplateTypePersistValidator.class)) + .failOn(DescriptionTemplateTypePersist._name).failWith(messageSource.getMessage("Validation_MaxLength", new Object[]{DescriptionTemplateTypePersist._name}, LocaleContextHolder.getLocale())) +// this.refSpec() +// .iff(() -> item.getObj() != null) +// .on(DescriptionTemplateTypePersist._obj) +// .over(item.getObj()) +// .using(() -> this.validatorFactory.validator(DescriptionTemplateTypePersistValidator.class)), +// this.navSpec() +// .iff(() -> item.getNested() != null) +// .on(DescriptionTemplateTypePersist._nested) +// .over(item.getNested()) +// .using(() -> this.validatorFactory.validator(DescriptionTemplateTypePersistValidator.class)) ); } } From f09e031e0cc3d5be3e5717f4d3407e3615cc85de Mon Sep 17 00:00:00 2001 From: sgiannopoulos Date: Tue, 19 Dec 2023 15:46:31 +0200 Subject: [PATCH 3/7] move old validation logic --- .../commons/validation/AbstractValidator.java | 115 ++++++++++++++++++ .../commons/validation/BaseValidator.java | 112 +---------------- .../validation/{ => old}/EnumNotNull.java | 2 +- .../{ => old}/FieldNotNullIfOtherSet.java | 2 +- .../FieldNotNullIfOtherSetValidator.java | 3 +- .../{ => old}/FieldsValueMatch.java | 2 +- .../{ => old}/FieldsValueMatchValidator.java | 3 +- .../{ => old}/RequiredOneField.java | 2 +- .../{ => old}/RequiredOneFieldValidator.java | 3 +- .../validation/{ => old}/ValidEnum.java | 3 +- .../commons/validation/{ => old}/ValidId.java | 2 +- .../{ => old}/ValidIdValidator.java | 3 +- .../{ => old}/ValidationServiceImpl.java | 2 +- .../persist/ActionConfirmationPersist.java | 6 +- .../eudat/model/persist/CloneDmpPersist.java | 2 +- .../model/persist/DescriptionPersist.java | 6 +- .../persist/DescriptionReferencePersist.java | 11 +- .../persist/DescriptionStatusPersist.java | 11 +- .../persist/DescriptionTemplatePersist.java | 10 +- .../DescriptionTemplateTypePersist.java | 3 - .../model/persist/DmpBlueprintPersist.java | 7 +- .../DmpDescriptionTemplatePersist.java | 4 +- .../eu/eudat/model/persist/DmpPersist.java | 7 +- .../model/persist/DmpReferencePersist.java | 4 +- .../model/persist/DmpUserInvitePersist.java | 2 +- .../persist/DmpUserInviteTypePersist.java | 2 +- .../model/persist/DmpUserRemovePersist.java | 13 +- .../eudat/model/persist/EntityDoiPersist.java | 4 +- .../eudat/model/persist/LanguagePersist.java | 2 +- .../eu/eudat/model/persist/LockPersist.java | 6 +- .../NewVersionDescriptionTemplatePersist.java | 6 +- .../model/persist/NewVersionDmpPersist.java | 4 +- .../eudat/model/persist/ReferencePersist.java | 6 +- .../model/persist/ReferenceTypePersist.java | 4 +- .../model/persist/StorageFilePersist.java | 2 +- .../persist/SupportiveMaterialPersist.java | 5 +- .../eu/eudat/model/persist/TenantPersist.java | 4 +- .../persist/UserAdditionalInfoPersist.java | 2 +- .../UserDescriptionTemplatePersist.java | 6 +- .../eu/eudat/model/persist/UserPersist.java | 15 +-- .../model/persist/UserRolePatchPersist.java | 8 +- .../model/persist/UserSettingsPersist.java | 4 +- .../DmpInvitationPersist.java | 6 +- .../model/persist/deposit/DepositRequest.java | 2 +- .../AutoCompleteSingleDataPersist.java | 2 +- .../fielddata/BaseFieldDataPersist.java | 2 +- .../fielddata/ExternalDatasetDataPersist.java | 2 +- .../DescriptionTemplatePersist.java | 2 +- .../ExtraFieldPersist.java | 2 +- .../dmpblueprintdefinition/FieldPersist.java | 4 +- .../SectionPersist.java | 2 +- .../SystemFieldPersist.java | 2 +- .../notification/NotificationPersist.java | 4 +- .../referencedefinition/FieldPersist.java | 2 +- .../AuthenticationConfigurationPersist.java | 2 +- .../ReferenceTypeFieldPersist.java | 2 +- ...nceTypeSourceBaseConfigurationPersist.java | 2 +- ...SourceExternalApiConfigurationPersist.java | 3 +- 58 files changed, 211 insertions(+), 250 deletions(-) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/validation/AbstractValidator.java rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ => old}/EnumNotNull.java (88%) rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ => old}/FieldNotNullIfOtherSet.java (93%) rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ => old}/FieldNotNullIfOtherSetValidator.java (91%) rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ => old}/FieldsValueMatch.java (94%) rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ => old}/FieldsValueMatchValidator.java (89%) rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ => old}/RequiredOneField.java (91%) rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ => old}/RequiredOneFieldValidator.java (91%) rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ => old}/ValidEnum.java (81%) rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ => old}/ValidId.java (90%) rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ => old}/ValidIdValidator.java (92%) rename dmp-backend/core/src/main/java/eu/eudat/commons/validation/{ => old}/ValidationServiceImpl.java (96%) diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/AbstractValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/AbstractValidator.java new file mode 100644 index 000000000..c45e7d282 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/AbstractValidator.java @@ -0,0 +1,115 @@ +package eu.eudat.commons.validation; + +import eu.eudat.commons.validation.specification.*; +import eu.eudat.convention.ConventionService; +import eu.eudat.errorcode.ErrorThesaurusProperties; +import gr.cite.tools.exception.MyValidationException; +import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.Errors; +import org.springframework.validation.FieldError; +import org.springframework.validation.ValidationUtils; + +import java.text.MessageFormat; +import java.util.*; + +public abstract class AbstractValidator implements Validator { + private BeanPropertyBindingResult bindingResult; + + protected abstract Class modelClass(); + + protected abstract List specifications(T item); + + @Override + public boolean supports(Class clazz) { + return clazz == null ? false : this.modelClass().equals(clazz); + } + + @Override + public void validate(Object obj, Errors e) { + if (obj == null) return; + T item = this.modelClass().cast(obj); + List specifications = this.specifications(item); + if (specifications == null) return;; + List propertySpecifications = specifications.stream().filter(x-> x instanceof PropertySpecification).map(x-> (PropertySpecification)x).toList(); + for (PropertySpecification propertySpecification : propertySpecifications){ + if ((propertySpecification.getPrecondition() == null || propertySpecification.getPrecondition().get()) && + (propertySpecification.getSpecification() == null || !propertySpecification.getSpecification().get()) + ){ + e.rejectValue(propertySpecification.getErrorKey(), propertySpecification.getErrorCode(), propertySpecification.getErrorMessage()); + } + } + + List navigationReferenceSpecifications = specifications.stream().filter(x-> x instanceof NavigationReferenceSpecification).map(x-> (NavigationReferenceSpecification)x).toList(); + for (NavigationReferenceSpecification navigationReferenceSpecification : navigationReferenceSpecifications){ + if (navigationReferenceSpecification.getReference() != null && (navigationReferenceSpecification.getPrecondition() == null || navigationReferenceSpecification.getPrecondition().get())){ + try { + e.pushNestedPath(navigationReferenceSpecification.getKey()); + ValidationUtils.invokeValidator(navigationReferenceSpecification.getValidator().get(), navigationReferenceSpecification.getReference(), e); + } finally { + e.popNestedPath(); + } + } + } + + List navigationDetailsSpecifications = specifications.stream().filter(x-> x instanceof NavigationDetailsSpecification).map(x-> (NavigationDetailsSpecification)x).toList(); + for (NavigationDetailsSpecification navigationDetailsSpecification : navigationDetailsSpecifications){ + if (navigationDetailsSpecification.getDetails() != null && (navigationDetailsSpecification.getPrecondition() == null || navigationDetailsSpecification.getPrecondition().get())){ + + for (int i = 0; i < navigationDetailsSpecification.getDetails().size(); i++) { + try { + e.pushNestedPath(MessageFormat.format("{0}[{1}]", navigationDetailsSpecification.getKey(), i)); + ValidationUtils.invokeValidator(navigationDetailsSpecification.getValidator().get(), navigationDetailsSpecification.getDetails().get(i), e); + } finally { + e.popNestedPath(); + } + } + } + } + } + + @Override + public void validate(Object target){ + this.bindingResult = new BeanPropertyBindingResult(target, target.getClass().getName()); + this.validate(target, this.bindingResult); + } + + @Override + public ValidationResult result() { + ValidationResult validationResult = new ValidationResult(); + if (this.bindingResult != null && bindingResult.hasErrors()){ + for (FieldError fieldError : bindingResult.getFieldErrors()){ + validationResult.add(new ValidationFailure(fieldError.getField(), fieldError.getDefaultMessage())); + } + } + return validationResult; + } + + protected List>> flattenValidationResult() { + ValidationResult result = result(); + List>> errorsMap = new ArrayList<>(); + for (ValidationFailure fieldError : result.getErrors()){ + Map.Entry> entry = errorsMap.stream().filter(x-> Objects.equals(x.getKey(), fieldError.getErrorKey())).findFirst().orElse(null); + if (entry == null) { + entry = new AbstractMap.SimpleEntry<>(fieldError.getErrorKey(), new ArrayList<>()); + errorsMap.add(entry); + } + entry.getValue().add(fieldError.getErrorMessage()); + } + + return errorsMap; + } + + protected PropertySpecificationBuilder spec() { + return new PropertySpecificationBuilder(); + } + + protected NavigationReferenceSpecificationBuilder refSpec() { + return new NavigationReferenceSpecificationBuilder(); + } + + protected NavigationDetailsSpecificationBuilder navSpec() + { + return new NavigationDetailsSpecificationBuilder(); + } +} + diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java index 1d8644200..829cfdd30 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java @@ -1,19 +1,11 @@ package eu.eudat.commons.validation; -import eu.eudat.commons.validation.specification.*; import eu.eudat.convention.ConventionService; import eu.eudat.errorcode.ErrorThesaurusProperties; import gr.cite.tools.exception.MyValidationException; -import org.springframework.validation.BeanPropertyBindingResult; -import org.springframework.validation.Errors; -import org.springframework.validation.FieldError; -import org.springframework.validation.ValidationUtils; - -import java.text.MessageFormat; import java.util.*; -public abstract class BaseValidator implements Validator { - private BeanPropertyBindingResult bindingResult; +public abstract class BaseValidator extends AbstractValidator { protected final ConventionService conventionService; protected final ErrorThesaurusProperties errors; @@ -21,117 +13,17 @@ public abstract class BaseValidator implements Validator { this.conventionService = conventionService; this.errors = errors; } - - protected abstract Class modelClass(); - - protected abstract List specifications(T item); - - @Override - public boolean supports(Class clazz) { - return clazz == null ? false : this.modelClass().equals(clazz); - } - - @Override - public void validate(Object obj, Errors e) { - if (obj == null) return; - T item = this.modelClass().cast(obj); - List specifications = this.specifications(item); - if (specifications == null) return;; - List propertySpecifications = specifications.stream().filter(x-> x instanceof PropertySpecification).map(x-> (PropertySpecification)x).toList(); - for (PropertySpecification propertySpecification : propertySpecifications){ - if ((propertySpecification.getPrecondition() == null || propertySpecification.getPrecondition().get()) && - (propertySpecification.getSpecification() == null || !propertySpecification.getSpecification().get()) - ){ - e.rejectValue(propertySpecification.getErrorKey(), propertySpecification.getErrorCode(), propertySpecification.getErrorMessage()); - } - } - - List navigationReferenceSpecifications = specifications.stream().filter(x-> x instanceof NavigationReferenceSpecification).map(x-> (NavigationReferenceSpecification)x).toList(); - for (NavigationReferenceSpecification navigationReferenceSpecification : navigationReferenceSpecifications){ - if (navigationReferenceSpecification.getReference() != null && (navigationReferenceSpecification.getPrecondition() == null || navigationReferenceSpecification.getPrecondition().get())){ - try { - e.pushNestedPath(navigationReferenceSpecification.getKey()); - ValidationUtils.invokeValidator(navigationReferenceSpecification.getValidator().get(), navigationReferenceSpecification.getReference(), e); - } finally { - e.popNestedPath(); - } - } - } - - List navigationDetailsSpecifications = specifications.stream().filter(x-> x instanceof NavigationDetailsSpecification).map(x-> (NavigationDetailsSpecification)x).toList(); - for (NavigationDetailsSpecification navigationDetailsSpecification : navigationDetailsSpecifications){ - if (navigationDetailsSpecification.getDetails() != null && (navigationDetailsSpecification.getPrecondition() == null || navigationDetailsSpecification.getPrecondition().get())){ - - for (int i = 0; i < navigationDetailsSpecification.getDetails().size(); i++) { - try { - e.pushNestedPath(MessageFormat.format("{0}[{1}]", navigationDetailsSpecification.getKey(), i)); - ValidationUtils.invokeValidator(navigationDetailsSpecification.getValidator().get(), navigationDetailsSpecification.getDetails().get(i), e); - } finally { - e.popNestedPath(); - } - } - } - } - } - - @Override - public void validate(Object target){ - this.bindingResult = new org.springframework.validation.BeanPropertyBindingResult(target, target.getClass().getName()); - this.validate(target, this.bindingResult); - } @Override public void validateForce(Object target) { this.validate(target); ValidationResult result = result(); - if (!result.isValid()){ + if (!result.isValid()) { List>> errorsMap = this.flattenValidationResult(); throw new MyValidationException(this.errors.getModelValidation().getCode(), errorsMap); } - } - protected List>> flattenValidationResult() { - ValidationResult result = result(); - List>> errorsMap = new ArrayList<>(); - for (ValidationFailure fieldError : result.getErrors()){ - Map.Entry> entry = errorsMap.stream().filter(x-> Objects.equals(x.getKey(), fieldError.getErrorKey())).findFirst().orElse(null); - if (entry == null) { - entry = new AbstractMap.SimpleEntry<>(fieldError.getErrorKey(), new ArrayList<>()); - errorsMap.add(entry); - } - entry.getValue().add(fieldError.getErrorMessage()); - } - - return errorsMap; - } - - protected PropertySpecificationBuilder spec() { - return new PropertySpecificationBuilder(); - } - - protected NavigationReferenceSpecificationBuilder refSpec() { - return new NavigationReferenceSpecificationBuilder(); - } - - protected NavigationDetailsSpecificationBuilder navSpec() - { - return new NavigationDetailsSpecificationBuilder(); - } - - @Override - public ValidationResult result() { - ValidationResult validationResult = new ValidationResult(); - if (this.bindingResult != null && bindingResult.hasErrors()){ - for (FieldError fieldError : bindingResult.getFieldErrors()){ - validationResult.add(new ValidationFailure(fieldError.getField(), fieldError.getDefaultMessage())); - } - } - return validationResult; - } - - - protected Boolean isValidGuid(UUID guid) { return this.conventionService.isValidGuid(guid); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/EnumNotNull.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/EnumNotNull.java similarity index 88% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/EnumNotNull.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/EnumNotNull.java index ffa2553b5..94003e578 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/EnumNotNull.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/EnumNotNull.java @@ -1,4 +1,4 @@ -package eu.eudat.commons.validation; +package eu.eudat.commons.validation.old; import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSet.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldNotNullIfOtherSet.java similarity index 93% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSet.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldNotNullIfOtherSet.java index 2b3893879..3014f1792 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSet.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldNotNullIfOtherSet.java @@ -1,4 +1,4 @@ -package eu.eudat.commons.validation; +package eu.eudat.commons.validation.old; import jakarta.validation.Constraint; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSetValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldNotNullIfOtherSetValidator.java similarity index 91% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSetValidator.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldNotNullIfOtherSetValidator.java index 1b55849f5..7bcd6acac 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSetValidator.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldNotNullIfOtherSetValidator.java @@ -1,5 +1,6 @@ -package eu.eudat.commons.validation; +package eu.eudat.commons.validation.old; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; import org.springframework.beans.BeanWrapperImpl; import jakarta.validation.ConstraintValidator; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatch.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldsValueMatch.java similarity index 94% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatch.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldsValueMatch.java index d08df40d0..5b411fe58 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatch.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldsValueMatch.java @@ -1,4 +1,4 @@ -package eu.eudat.commons.validation; +package eu.eudat.commons.validation.old; import jakarta.validation.Constraint; import jakarta.validation.Payload; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatchValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldsValueMatchValidator.java similarity index 89% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatchValidator.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldsValueMatchValidator.java index 1f4691378..7706cd483 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatchValidator.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/FieldsValueMatchValidator.java @@ -1,5 +1,6 @@ -package eu.eudat.commons.validation; +package eu.eudat.commons.validation.old; +import eu.eudat.commons.validation.old.FieldsValueMatch; import org.springframework.beans.BeanWrapperImpl; import jakarta.validation.ConstraintValidator; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/RequiredOneField.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/RequiredOneField.java similarity index 91% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/RequiredOneField.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/RequiredOneField.java index 1c42ea6f4..c461f924a 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/RequiredOneField.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/RequiredOneField.java @@ -1,4 +1,4 @@ -package eu.eudat.commons.validation; +package eu.eudat.commons.validation.old; import jakarta.validation.Constraint; import jakarta.validation.Payload; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/RequiredOneFieldValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/RequiredOneFieldValidator.java similarity index 91% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/RequiredOneFieldValidator.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/RequiredOneFieldValidator.java index 6b1cc6c5f..b999b9470 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/RequiredOneFieldValidator.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/RequiredOneFieldValidator.java @@ -1,5 +1,6 @@ -package eu.eudat.commons.validation; +package eu.eudat.commons.validation.old; +import eu.eudat.commons.validation.old.RequiredOneField; import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; import org.apache.commons.beanutils.PropertyUtils; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidEnum.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidEnum.java similarity index 81% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidEnum.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidEnum.java index 079f9e64a..ce0c8f125 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidEnum.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidEnum.java @@ -1,5 +1,6 @@ -package eu.eudat.commons.validation; +package eu.eudat.commons.validation.old; +import eu.eudat.commons.validation.old.EnumNotNull; import jakarta.validation.Constraint; import jakarta.validation.Payload; import java.lang.annotation.*; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidId.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidId.java similarity index 90% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidId.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidId.java index 2f470b57b..f8a9115d6 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidId.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidId.java @@ -1,4 +1,4 @@ -package eu.eudat.commons.validation; +package eu.eudat.commons.validation.old; import jakarta.validation.Constraint; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidIdValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidIdValidator.java similarity index 92% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidIdValidator.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidIdValidator.java index 7fce85251..fa71ff4c8 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidIdValidator.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidIdValidator.java @@ -1,5 +1,6 @@ -package eu.eudat.commons.validation; +package eu.eudat.commons.validation.old; +import eu.eudat.commons.validation.old.ValidId; import eu.eudat.convention.ConventionService; import org.springframework.beans.factory.annotation.Autowired; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidationServiceImpl.java similarity index 96% rename from dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationServiceImpl.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidationServiceImpl.java index 33cfa570c..a98561485 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/old/ValidationServiceImpl.java @@ -1,4 +1,4 @@ -package eu.eudat.commons.validation; +package eu.eudat.commons.validation.old; import eu.eudat.errorcode.ErrorThesaurusProperties; import gr.cite.tools.exception.MyValidationException; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/ActionConfirmationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/ActionConfirmationPersist.java index 1f1240064..b1993da53 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/ActionConfirmationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/ActionConfirmationPersist.java @@ -2,9 +2,9 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.ActionConfirmationStatus; import eu.eudat.commons.enums.ActionConfirmationType; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import eu.eudat.model.persist.actionconfirmation.DmpInvitationPersist; import eu.eudat.model.persist.actionconfirmation.EmailConfirmationPersist; import jakarta.validation.Valid; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/CloneDmpPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/CloneDmpPersist.java index 1a34a8e96..3a4c80277 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/CloneDmpPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/CloneDmpPersist.java @@ -1,6 +1,6 @@ package eu.eudat.model.persist; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import org.apache.commons.compress.utils.Lists; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionPersist.java index af6a8c9e8..2332c235f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionPersist.java @@ -1,9 +1,9 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.DescriptionStatus; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import eu.eudat.data.DescriptionEntity; import eu.eudat.model.persist.descriptionproperties.PropertyDefinitionPersist; import jakarta.validation.Valid; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionReferencePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionReferencePersist.java index 070b39000..59ad3732b 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionReferencePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionReferencePersist.java @@ -1,18 +1,11 @@ package eu.eudat.model.persist; -import eu.eudat.commons.enums.DescriptionTemplateStatus; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; -import eu.eudat.data.DescriptionTemplateEntity; -import eu.eudat.model.persist.descriptiontemplatedefinition.DefinitionPersist; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.Valid; -import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.List; import java.util.UUID; @FieldNotNullIfOtherSet(message = "{validation.hashempty}") diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionStatusPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionStatusPersist.java index 7c092f29f..a9d623447 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionStatusPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionStatusPersist.java @@ -1,17 +1,12 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.DescriptionStatus; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; -import eu.eudat.data.DescriptionEntity; -import eu.eudat.model.persist.descriptionproperties.PropertyDefinitionPersist; -import jakarta.validation.Valid; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.List; import java.util.UUID; @FieldNotNullIfOtherSet(message = "{validation.hashempty}") diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplatePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplatePersist.java index a2a3b1b34..cde3040b5 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplatePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplatePersist.java @@ -2,19 +2,15 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.DescriptionTemplateStatus; -import eu.eudat.commons.enums.UserDescriptionTemplateRole; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import eu.eudat.data.DescriptionTemplateEntity; import eu.eudat.model.persist.descriptiontemplatedefinition.DefinitionPersist; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import org.springframework.validation.Errors; -import org.springframework.validation.ValidationUtils; -import org.springframework.validation.Validator; import java.util.List; import java.util.UUID; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java index 94c19c901..b3b960ec7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java @@ -8,9 +8,6 @@ import eu.eudat.commons.validation.specification.Specification; import eu.eudat.convention.ConventionService; import eu.eudat.data.DescriptionTemplateTypeEntity; import eu.eudat.errorcode.ErrorThesaurusProperties; -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Scope; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpBlueprintPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpBlueprintPersist.java index 4bbd57818..e455736ef 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpBlueprintPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpBlueprintPersist.java @@ -1,11 +1,10 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.DmpBlueprintStatus; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import eu.eudat.data.DmpBlueprintEntity; -import eu.eudat.model.dmpblueprintdefinition.Definition; import eu.eudat.model.persist.dmpblueprintdefinition.DefinitionPersist; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpDescriptionTemplatePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpDescriptionTemplatePersist.java index c34538289..1c5d12ce1 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpDescriptionTemplatePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpDescriptionTemplatePersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotNull; import java.util.UUID; 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 f5b56a483..2c7d551f0 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 @@ -2,10 +2,9 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.DmpAccessType; import eu.eudat.commons.enums.DmpStatus; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; -import eu.eudat.data.DescriptionEntity; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import eu.eudat.data.DmpEntity; import eu.eudat.model.persist.dmpproperties.DmpPropertiesPersist; import jakarta.validation.Valid; 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 index bdb0209bf..0fac4da79 100644 --- 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 @@ -1,7 +1,7 @@ package eu.eudat.model.persist; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserInvitePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserInvitePersist.java index 9eb8aa670..1b9a34e75 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserInvitePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserInvitePersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.DmpUserRole; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserInviteTypePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserInviteTypePersist.java index 3d1fd7f4d..ee01ad183 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserInviteTypePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserInviteTypePersist.java @@ -1,6 +1,6 @@ package eu.eudat.model.persist; -import eu.eudat.commons.validation.RequiredOneField; +import eu.eudat.commons.validation.old.RequiredOneField; import java.util.UUID; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserRemovePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserRemovePersist.java index 20dc12ff3..11673e474 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserRemovePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DmpUserRemovePersist.java @@ -1,19 +1,10 @@ package eu.eudat.model.persist; -import eu.eudat.commons.enums.DmpAccessType; -import eu.eudat.commons.enums.DmpStatus; import eu.eudat.commons.enums.DmpUserRole; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; -import eu.eudat.data.DmpEntity; -import eu.eudat.model.persist.dmpproperties.DmpPropertiesPersist; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotEmpty; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import java.util.List; import java.util.UUID; public class DmpUserRemovePersist { diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/EntityDoiPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/EntityDoiPersist.java index 96d57d5d9..1db790df3 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/EntityDoiPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/EntityDoiPersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidId; import java.util.UUID; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/LanguagePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/LanguagePersist.java index af86bab75..81d21f039 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/LanguagePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/LanguagePersist.java @@ -1,6 +1,6 @@ package eu.eudat.model.persist; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/LockPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/LockPersist.java index 1bbed6894..b62060408 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/LockPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/LockPersist.java @@ -1,9 +1,9 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.LockTargetType; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.Valid; import java.util.UUID; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/NewVersionDescriptionTemplatePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/NewVersionDescriptionTemplatePersist.java index e99902c99..c9adf070c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/NewVersionDescriptionTemplatePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/NewVersionDescriptionTemplatePersist.java @@ -2,9 +2,9 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.DescriptionTemplateStatus; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import eu.eudat.data.DescriptionTemplateEntity; import eu.eudat.model.persist.descriptiontemplatedefinition.DefinitionPersist; import jakarta.validation.Valid; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/NewVersionDmpPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/NewVersionDmpPersist.java index c0dbe35b1..d0b375a8f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/NewVersionDmpPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/NewVersionDmpPersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import org.apache.commons.compress.utils.Lists; 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 1c2efdb6b..694216cc5 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 @@ -2,9 +2,9 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.ReferenceType; import eu.eudat.commons.enums.ReferenceSourceType; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import eu.eudat.model.persist.referencedefinition.DefinitionPersist; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferenceTypePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferenceTypePersist.java index 195d521eb..0c65a0fe5 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferenceTypePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/ReferenceTypePersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidId; import eu.eudat.model.persist.referencetypedefinition.ReferenceTypeDefinitionPersist; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/StorageFilePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/StorageFilePersist.java index 55a8df9d2..62c73983d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/StorageFilePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/StorageFilePersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.StorageType; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; import eu.eudat.data.StorageFileEntity; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; 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 79fbcd2db..362f46a9b 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 @@ -1,9 +1,8 @@ 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 eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/TenantPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/TenantPersist.java index e9ddab198..4c1935883 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/TenantPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/TenantPersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidId; import eu.eudat.model.persist.tenantconfig.TenantConfigPersist; import jakarta.validation.constraints.*; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserAdditionalInfoPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserAdditionalInfoPersist.java index 20744529e..34881a55d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserAdditionalInfoPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserAdditionalInfoPersist.java @@ -1,6 +1,6 @@ package eu.eudat.model.persist; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserDescriptionTemplatePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserDescriptionTemplatePersist.java index cc5fb3ade..a829bf95e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserDescriptionTemplatePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserDescriptionTemplatePersist.java @@ -1,9 +1,9 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.UserDescriptionTemplateRole; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotNull; import java.util.UUID; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserPersist.java index 7f37c9865..f430d40b6 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserPersist.java @@ -1,25 +1,14 @@ package eu.eudat.model.persist; -import eu.eudat.commons.enums.DescriptionTemplateTypeStatus; -import eu.eudat.commons.enums.IsActive; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; -import eu.eudat.data.DescriptionEntity; -import eu.eudat.data.DescriptionTemplateTypeEntity; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidId; import eu.eudat.data.UserEntity; -import eu.eudat.model.UserAdditionalInfo; -import eu.eudat.model.UserContactInfo; -import eu.eudat.model.UserCredential; -import eu.eudat.model.UserRole; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import java.time.Instant; -import java.util.List; import java.util.UUID; @FieldNotNullIfOtherSet(message = "{validation.hashempty}") diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserRolePatchPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserRolePatchPersist.java index fceb1e87a..d8a821de8 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserRolePatchPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserRolePatchPersist.java @@ -1,13 +1,9 @@ package eu.eudat.model.persist; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidId; -import eu.eudat.data.UserEntity; -import jakarta.validation.Valid; -import jakarta.validation.constraints.NotEmpty; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; import java.util.List; import java.util.UUID; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserSettingsPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserSettingsPersist.java index 2e065fd4f..09bc030db 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserSettingsPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserSettingsPersist.java @@ -1,8 +1,8 @@ package eu.eudat.model.persist; import eu.eudat.commons.enums.UserSettingsType; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/actionconfirmation/DmpInvitationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/actionconfirmation/DmpInvitationPersist.java index e646bc8ce..4d1ef7688 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/actionconfirmation/DmpInvitationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/actionconfirmation/DmpInvitationPersist.java @@ -1,14 +1,10 @@ package eu.eudat.model.persist.actionconfirmation; import eu.eudat.commons.enums.DmpUserRole; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; -import jakarta.xml.bind.annotation.XmlAccessType; -import jakarta.xml.bind.annotation.XmlAccessorType; -import jakarta.xml.bind.annotation.XmlAttribute; -import jakarta.xml.bind.annotation.XmlRootElement; import java.util.UUID; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/deposit/DepositRequest.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/deposit/DepositRequest.java index 09f737267..76dad069b 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/deposit/DepositRequest.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/deposit/DepositRequest.java @@ -1,6 +1,6 @@ package eu.eudat.model.persist.deposit; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.ValidId; import gr.cite.tools.fieldset.BaseFieldSet; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/AutoCompleteSingleDataPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/AutoCompleteSingleDataPersist.java index 262083e6c..c300150cc 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/AutoCompleteSingleDataPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/AutoCompleteSingleDataPersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist.descriptiontemplatedefinition.fielddata; import eu.eudat.commons.types.descriptiontemplate.fielddata.AutoCompleteDataEntity; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/BaseFieldDataPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/BaseFieldDataPersist.java index 9ad85891d..f64f5eaee 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/BaseFieldDataPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/BaseFieldDataPersist.java @@ -3,7 +3,7 @@ package eu.eudat.model.persist.descriptiontemplatedefinition.fielddata; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import eu.eudat.commons.enums.FieldType; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/ExternalDatasetDataPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/ExternalDatasetDataPersist.java index c345a7dab..6ade782c9 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/ExternalDatasetDataPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/fielddata/ExternalDatasetDataPersist.java @@ -2,7 +2,7 @@ package eu.eudat.model.persist.descriptiontemplatedefinition.fielddata; import eu.eudat.commons.enums.FieldDataExternalDatasetType; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; import jakarta.validation.constraints.NotNull; public class ExternalDatasetDataPersist extends BaseFieldDataPersist { diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/DescriptionTemplatePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/DescriptionTemplatePersist.java index 781cb7fe3..f46e0aa67 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/DescriptionTemplatePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/DescriptionTemplatePersist.java @@ -1,6 +1,6 @@ package eu.eudat.model.persist.dmpblueprintdefinition; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/ExtraFieldPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/ExtraFieldPersist.java index 296cc4ed3..566784fb9 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/ExtraFieldPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/ExtraFieldPersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist.dmpblueprintdefinition; import eu.eudat.commons.enums.DmpBlueprintExtraFieldDataType; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; public class ExtraFieldPersist extends FieldPersist { diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/FieldPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/FieldPersist.java index 4b4c5363b..48a6308ca 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/FieldPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/FieldPersist.java @@ -3,8 +3,8 @@ package eu.eudat.model.persist.dmpblueprintdefinition; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import eu.eudat.commons.enums.DmpBlueprintFieldCategory; -import eu.eudat.commons.validation.ValidEnum; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.ValidEnum; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SectionPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SectionPersist.java index 3ae066faa..73809832a 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SectionPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SectionPersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist.dmpblueprintdefinition; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SystemFieldPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SystemFieldPersist.java index e160ba582..b2dfe1fe5 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SystemFieldPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/dmpblueprintdefinition/SystemFieldPersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist.dmpblueprintdefinition; import eu.eudat.commons.enums.DmpBlueprintSystemFieldType; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; public class SystemFieldPersist extends FieldPersist { @ValidEnum(message = "{validation.empty}") diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/notification/NotificationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/notification/NotificationPersist.java index 358556800..71228d9ad 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/notification/NotificationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/notification/NotificationPersist.java @@ -4,8 +4,8 @@ import eu.eudat.commons.enums.notification.NotificationContactType; import eu.eudat.commons.enums.notification.NotificationNotifyState; import eu.eudat.commons.enums.notification.NotificationTrackingProcess; import eu.eudat.commons.enums.notification.NotificationTrackingState; -import eu.eudat.commons.validation.FieldNotNullIfOtherSet; -import eu.eudat.commons.validation.ValidId; +import eu.eudat.commons.validation.old.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.old.ValidId; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencedefinition/FieldPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencedefinition/FieldPersist.java index 0a53aaadc..5acd9eb51 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencedefinition/FieldPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencedefinition/FieldPersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist.referencedefinition; import eu.eudat.commons.enums.ReferenceFieldDataType; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/AuthenticationConfigurationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/AuthenticationConfigurationPersist.java index f3045b42d..75a718ede 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/AuthenticationConfigurationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/AuthenticationConfigurationPersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist.referencetypedefinition; import eu.eudat.commons.enums.ReferenceTypeExternalApiHTTPMethodType; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; import jakarta.validation.constraints.NotNull; public class AuthenticationConfigurationPersist { diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeFieldPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeFieldPersist.java index 3db61b247..8dfff57d4 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeFieldPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeFieldPersist.java @@ -1,7 +1,7 @@ package eu.eudat.model.persist.referencetypedefinition; import eu.eudat.commons.enums.ReferenceFieldDataType; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceBaseConfigurationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceBaseConfigurationPersist.java index 63a3c93c5..8cba296cc 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceBaseConfigurationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceBaseConfigurationPersist.java @@ -3,7 +3,7 @@ package eu.eudat.model.persist.referencetypedefinition; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import eu.eudat.commons.enums.ReferenceTypeSourceType; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceExternalApiConfigurationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceExternalApiConfigurationPersist.java index 34753e333..07b5cb5bf 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceExternalApiConfigurationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceExternalApiConfigurationPersist.java @@ -1,8 +1,7 @@ package eu.eudat.model.persist.referencetypedefinition; import eu.eudat.commons.enums.ReferenceTypeExternalApiHTTPMethodType; -import eu.eudat.commons.enums.ReferenceTypeSourceType; -import eu.eudat.commons.validation.ValidEnum; +import eu.eudat.commons.validation.old.ValidEnum; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; From f9a47f2de7b915f7595a409310cfd3744209871a Mon Sep 17 00:00:00 2001 From: Thomas Georgios Giannos Date: Tue, 19 Dec 2023 15:57:13 +0200 Subject: [PATCH 4/7] Refactoring license migration --- .../elastic/criteria/DatasetCriteria.java | 9 ++ .../elastic/repository/DatasetRepository.java | 32 ++++- .../elastic/repository/ElasticRepository.java | 2 +- .../eudat/migration/DmpMigrationService.java | 136 ++++++++++++------ .../eudat/migration/TagMigrationService.java | 13 +- .../migration/MigrationController.java | 8 ++ 6 files changed, 144 insertions(+), 56 deletions(-) diff --git a/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/criteria/DatasetCriteria.java b/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/criteria/DatasetCriteria.java index 4443c84aa..6e5872b4c 100644 --- a/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/criteria/DatasetCriteria.java +++ b/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/criteria/DatasetCriteria.java @@ -12,6 +12,7 @@ public class DatasetCriteria extends Criteria { private String like; private List datasetTemplates; private Short status; + private List ids; private List dmps; private List groupIds; private List grants; @@ -50,6 +51,14 @@ public class DatasetCriteria extends Criteria { this.status = status; } + public List getIds() { + return ids; + } + + public void setIds(List ids) { + this.ids = ids; + } + public List getDmps() { return dmps; } diff --git a/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/repository/DatasetRepository.java b/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/repository/DatasetRepository.java index d1ed9c5c9..202e36cf7 100644 --- a/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/repository/DatasetRepository.java +++ b/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/repository/DatasetRepository.java @@ -1,5 +1,6 @@ package eu.old.eudat.elastic.repository; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.old.eudat.elastic.criteria.DatasetCriteria; import eu.old.eudat.elastic.entities.Dataset; import eu.old.eudat.elastic.entities.Dmp; @@ -13,10 +14,8 @@ import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; -import org.elasticsearch.index.query.BoolQueryBuilder; -import org.elasticsearch.index.query.InnerHitBuilder; -import org.elasticsearch.index.query.NestedQueryBuilder; -import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.index.query.*; +import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.filter.FiltersAggregationBuilder; @@ -78,6 +77,24 @@ public class DatasetRepository extends ElasticRepository findByIds(List ids) throws IOException { + if (this.getClient() != null) { + SearchRequest searchRequest = new SearchRequest(this.environment.getProperty("elasticsearch.index")); + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + BoolQueryBuilder boolQuery = QueryBuilders.boolQuery().should(QueryBuilders.termsQuery("datasets.id.keyword", ids)); + NestedQueryBuilder nestedQueryBuilder = QueryBuilders.nestedQuery( "datasets", boolQuery, ScoreMode.Avg).innerHit(new InnerHitBuilder()); + searchSourceBuilder.query(nestedQueryBuilder); + searchSourceBuilder.size(100000); + searchRequest.source(searchSourceBuilder); + SearchResponse response = this.getClient().search(searchRequest, RequestOptions.DEFAULT); + return Arrays.stream(response.getHits().getHits()) + .map(hit -> hit.getInnerHits().values()).flatMap(Collection::stream) + .map(SearchHits::getHits).flatMap(Arrays::stream) + .map(x -> new Dataset().fromElasticEntity(this.transformFromString(x.getSourceAsString(), Map.class))).toList(); + } + return null; + } + @Override public Dataset findDocument(String id) throws IOException { if (this.getClient() != null) { @@ -205,7 +222,7 @@ public class DatasetRepository extends ElasticRepository 0) { + criteria.setIds(criteria.getIds().stream().filter(Objects::nonNull).collect(Collectors.toList())); + boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.id.keyword", criteria.getIds().stream().map(UUID::toString).collect(Collectors.toList()))); + } + if (criteria.getDmps() != null && criteria.getDmps().size() > 0) { criteria.setDmps(criteria.getDmps().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.dmp", criteria.getDmps().stream().map(UUID::toString).collect(Collectors.toList()))); diff --git a/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/repository/ElasticRepository.java b/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/repository/ElasticRepository.java index 1f8090392..fb2a2e405 100644 --- a/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/repository/ElasticRepository.java +++ b/dmp-migration-tool/elastic/src/main/java/eu/old/eudat/elastic/repository/ElasticRepository.java @@ -13,7 +13,7 @@ import java.io.IOException; /** * Created by ikalyvas on 7/5/2018. */ -public abstract class ElasticRepository implements Repository { +public abstract class ElasticRepository,C extends Criteria> implements Repository { private static final Logger logger = LoggerFactory.getLogger(ElasticRepository.class); private RestHighLevelClient client; diff --git a/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DmpMigrationService.java b/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DmpMigrationService.java index 17e74944a..5f3709b8c 100644 --- a/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DmpMigrationService.java +++ b/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DmpMigrationService.java @@ -118,53 +118,6 @@ public class DmpMigrationService { contactEntity.setUserId((String) model.getExtraProperties().get("contact")); dmpProperties.getContacts().add(contactEntity); } - if (model.getExtraProperties().containsKey("license") && model.getExtraProperties().get("license") != null) { - Object license = model.getExtraProperties().get("license"); - HashMap licenseMap = jsonHandlingService.mapFromJson(jsonHandlingService.toJson(license)); - ReferenceEntity referenceEntity = new ReferenceEntity(); - if (licenseMap.containsKey("pid")) { - referenceEntity.setReference(licenseMap.get("pid")); - } - ReferenceQuery referenceQuery = queryFactory.query(ReferenceQuery.class) - .references(referenceEntity.getReference()) - .types(ReferenceType.Licenses) - .isActive(IsActive.Active); - List foundReferences = referenceQuery.collect(); - boolean licenseExists = foundReferences != null && !foundReferences.isEmpty(); - if (!licenseExists) { - if (licenseMap.containsKey("name")) { - referenceEntity.setLabel(licenseMap.get("name")); - } - if (licenseMap.containsKey("uri")) { - referenceEntity.setSource(licenseMap.get("uri")); - } - if (licenseMap.containsKey("abbreviation")) { - referenceEntity.setAbbreviation(licenseMap.get("abbreviation")); - } - referenceEntity.setId(UUID.randomUUID()); - referenceEntity.setSourceType(ReferenceSourceType.External); - referenceEntity.setType(ReferenceType.Licenses); - referenceEntity.setCreatedAt(Instant.now()); - referenceEntity.setUpdatedAt(Instant.now()); - referenceEntity.setIsActive(IsActive.Active); - } - - DmpReferenceEntity dmpReferenceEntity = new DmpReferenceEntity(); - dmpReferenceEntity.setId(UUID.randomUUID()); - dmpReferenceEntity.setDmpId(data.getId()); - if (licenseExists) { - dmpReferenceEntity.setReferenceId(foundReferences.getFirst().getId()); - } else { - dmpReferenceEntity.setReferenceId(referenceEntity.getId()); - } - dmpReferenceEntity.setCreatedAt(Instant.now()); - dmpReferenceEntity.setUpdatedAt(Instant.now()); - dmpReferenceEntity.setIsActive(IsActive.Active); - - if (!licenseExists) - entityManager.persist(referenceEntity); - entityManager.persist(dmpReferenceEntity); - } } if (model.getProperties() != null) { model.getProperties().forEach((key,val) -> { @@ -205,4 +158,93 @@ public class DmpMigrationService { } while (items != null && !items.isEmpty() && !TestMode); } + public void migrateDmpLicenses() throws JsonProcessingException { + DMPDao dmpDao = databaseRepository.getDmpDao(); + long total = dmpDao.asQueryable().count(); + logger.debug("Migrate Licenses for Dmp Total : " + total); + int page = 0; + + Set collectedLicenses = new HashSet<>(); + Map licenseIdByName = new HashMap<>(); + List items; + do { + items = dmpDao.asQueryable().orderBy((builder, root) -> builder.asc(root.get("created"))).orderBy((builder, root) -> builder.asc(root.get("ID"))).skip(page * PageSize).take(PageSize).toList(); + + if (items != null && !items.isEmpty()) { + logger.debug("Migrate Licenses for Dmp " + page * PageSize + " of " + total); + + for (DMP item : items) { + DataManagementPlan model = new DataManagementPlan(); + model.fromDataModel(item); + if (model.getExtraProperties() != null) { + if (model.getExtraProperties().containsKey("license") && model.getExtraProperties().get("license") != null) { + Object license = model.getExtraProperties().get("license"); + HashMap licenseMap = jsonHandlingService.mapFromJson(jsonHandlingService.toJson(license)); + ReferenceEntity referenceEntity = new ReferenceEntity(); + String licensePid; + if (licenseMap.containsKey("pid") && licenseMap.get("pid") != null) { + licensePid = licenseMap.get("pid"); + referenceEntity.setReference(licensePid); + } + else + continue; + boolean licenseExists = collectedLicenses.contains(licensePid); + if (!licenseExists) { + if (licenseMap.containsKey("name")) { + referenceEntity.setLabel(licenseMap.get("name")); + } + if (licenseMap.containsKey("uri")) { + referenceEntity.setSource(licenseMap.get("uri")); + } + if (licenseMap.containsKey("abbreviation")) { + referenceEntity.setAbbreviation(licenseMap.get("abbreviation")); + } + if (licenseMap.containsKey("source") && licenseMap.get("source") != null) { + logger.debug("License found with source '{}'", licenseMap.get("source")); + } + if (licenseMap.containsKey("created") && licenseMap.get("created") != null) { + referenceEntity.setUpdatedAt(Instant.parse(licenseMap.get("created"))); + } else { + referenceEntity.setCreatedAt(Instant.now()); + } + if (licenseMap.containsKey("modified") && licenseMap.get("modified") != null) { + referenceEntity.setUpdatedAt(Instant.parse(licenseMap.get("modified"))); + } else { + referenceEntity.setUpdatedAt(Instant.now()); + } +// if (licenseMap.containsKey("tag") && licenseMap.get("tag") != null && !"Open Definition".equals(licenseMap.get("tag"))) { +// logger.debug("License found with tag '{}'", licenseMap.get("tag")); +// } + referenceEntity.setId(UUID.randomUUID()); + referenceEntity.setSourceType(ReferenceSourceType.External); + referenceEntity.setType(ReferenceType.Licenses); + referenceEntity.setIsActive(IsActive.Active); + + collectedLicenses.add(licensePid); + licenseIdByName.put(licensePid, referenceEntity.getId()); + logger.debug("License '{}' migrated", licensePid); + } + + DmpReferenceEntity dmpReferenceEntity = new DmpReferenceEntity(); + dmpReferenceEntity.setId(UUID.randomUUID()); + dmpReferenceEntity.setDmpId(item.getId()); + dmpReferenceEntity.setReferenceId(licenseIdByName.get(licensePid)); + dmpReferenceEntity.setCreatedAt(Instant.now()); + dmpReferenceEntity.setUpdatedAt(Instant.now()); + dmpReferenceEntity.setIsActive(IsActive.Active); + + if (!licenseExists) + entityManager.persist(referenceEntity); + entityManager.persist(dmpReferenceEntity); + } + } + this.entityManager.flush(); + } + + page++; + } + } while (items != null && !items.isEmpty() && !TestMode); + logger.info("Dmp licenses migration finished"); + } + } diff --git a/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/TagMigrationService.java b/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/TagMigrationService.java index 70891f59e..d590ea300 100644 --- a/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/TagMigrationService.java +++ b/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/TagMigrationService.java @@ -7,6 +7,7 @@ import eu.eudat.data.DescriptionTagEntity; import eu.eudat.data.TagEntity; import eu.old.eudat.data.dao.entities.DatasetDao; import eu.old.eudat.data.entities.Dataset; +import eu.old.eudat.elastic.criteria.DatasetCriteria; import eu.old.eudat.elastic.entities.Tag; import eu.old.eudat.elastic.repository.DatasetRepository; import eu.old.eudat.logic.services.operations.DatabaseRepository; @@ -50,18 +51,24 @@ public class TagMigrationService { Set savedTagNames = new HashSet<>(); Map savedTagIdsByName = new HashMap<>(); + DatasetCriteria criteria = new DatasetCriteria(); List items; do { items = datasetDao.asQueryable().orderBy((builder, root) -> builder.asc(root.get("created"))).orderBy((builder, root) -> builder.asc(root.get("ID"))).skip(page * PageSize).take(PageSize).toList(); if (items != null && !items.isEmpty()) { logger.debug("Migrate Dataset tags " + page * PageSize + " of " + total); - for (Dataset item : items) { - eu.old.eudat.elastic.entities.Dataset elasticDataset = this.datasetRepository.findDocument(item.getId().toString()); - if (elasticDataset == null) { + criteria.setIds(items.stream().map(Dataset::getId).toList()); +// List elasticDatasets = this.datasetRepository.queryIds(criteria); + List elasticDatasets = this.datasetRepository.findByIds(items.stream().map(x -> x.getId().toString()).toList()); + + for (Dataset item : items) { + List found = elasticDatasets.stream().filter(x -> item.getId().toString().equals(x.getId())).toList(); + if (found.isEmpty()) { logger.error("No dataset with id {} found on elastic search. Skipping tag migration for this dataset", item.getId()); continue; } + eu.old.eudat.elastic.entities.Dataset elasticDataset = found.getFirst(); boolean tagAlreadyExists; if (elasticDataset.getTags() != null && !elasticDataset.getTags().isEmpty()) { for(Tag tag : elasticDataset.getTags()) { diff --git a/dmp-migration-tool/web/src/main/java/eu/old/eudat/publicapi/migration/MigrationController.java b/dmp-migration-tool/web/src/main/java/eu/old/eudat/publicapi/migration/MigrationController.java index 1e22031de..55936b0fe 100644 --- a/dmp-migration-tool/web/src/main/java/eu/old/eudat/publicapi/migration/MigrationController.java +++ b/dmp-migration-tool/web/src/main/java/eu/old/eudat/publicapi/migration/MigrationController.java @@ -87,6 +87,7 @@ public class MigrationController { this.serviceMigrationService.migrate(); this.dmpMigrationService.migrate(); + this.dmpMigrationService.migrateDmpLicenses(); this.dmpDatasetProfileMigrationService.migrate(); this.datasetMigrationService.migrate(); this.tagMigrationService.migrate(); @@ -125,6 +126,13 @@ public class MigrationController { return true; } + @GetMapping("dmps/licenses") + @Transactional + public boolean migrateDmpLicenses() throws JsonProcessingException, NoSuchFieldException, IllegalAccessException { + this.dmpMigrationService.migrateDmpLicenses(); + return true; + } + @GetMapping("datasets") @Transactional public boolean migrateDatasets() throws IOException, JAXBException, ParserConfigurationException, InstantiationException, IllegalAccessException, SAXException { From aa648cda1deb14d469ed6352c73517d7d55cb3ef Mon Sep 17 00:00:00 2001 From: Thomas Georgios Giannos Date: Tue, 19 Dec 2023 16:37:54 +0200 Subject: [PATCH 5/7] Adding definitions info on migrated licenses --- .../eudat/migration/DmpMigrationService.java | 61 ++++++++++++++----- .../resources/config/application.properties | 1 + 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DmpMigrationService.java b/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DmpMigrationService.java index 5f3709b8c..72856e5ad 100644 --- a/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DmpMigrationService.java +++ b/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DmpMigrationService.java @@ -6,10 +6,14 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.type.MapType; import com.fasterxml.jackson.databind.type.TypeFactory; import eu.eudat.commons.JsonHandlingService; +import eu.eudat.commons.XmlHandlingService; import eu.eudat.commons.enums.*; import eu.eudat.commons.types.dmp.DmpBlueprintValueEntity; import eu.eudat.commons.types.dmp.DmpContactEntity; import eu.eudat.commons.types.dmp.DmpPropertiesEntity; +import eu.eudat.commons.types.reference.DefinitionEntity; +import eu.eudat.commons.types.reference.FieldEntity; +import eu.eudat.convention.ConventionService; import eu.eudat.data.DmpEntity; import eu.eudat.data.DmpReferenceEntity; import eu.eudat.data.ReferenceEntity; @@ -23,6 +27,7 @@ import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.logging.LoggerService; import jakarta.persistence.EntityManager; import org.slf4j.LoggerFactory; +import org.springframework.core.env.Environment; import org.springframework.stereotype.Service; import java.lang.reflect.Field; @@ -34,20 +39,22 @@ public class DmpMigrationService { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpMigrationService.class)); private final DatabaseRepository databaseRepository; - private final JsonHandlingService jsonHandlingService; private final EntityManager entityManager; - - private final QueryFactory queryFactory; + private final ConventionService conventionService; + private final XmlHandlingService xmlHandlingService; + private final Environment environment; private static final int PageSize = 500; private static final boolean TestMode = false; - public DmpMigrationService(DatabaseRepository databaseRepository, JsonHandlingService jsonHandlingService, EntityManager entityManager, QueryFactory queryFactory) { + public DmpMigrationService(DatabaseRepository databaseRepository, JsonHandlingService jsonHandlingService, EntityManager entityManager, ConventionService conventionService, XmlHandlingService xmlHandlingService, Environment environment) { this.databaseRepository = databaseRepository; this.jsonHandlingService = jsonHandlingService; this.entityManager = entityManager; - this.queryFactory = queryFactory; + this.conventionService = conventionService; + this.xmlHandlingService = xmlHandlingService; + this.environment = environment; } public void migrate() throws JsonProcessingException, NoSuchFieldException, IllegalAccessException { @@ -179,7 +186,7 @@ public class DmpMigrationService { if (model.getExtraProperties() != null) { if (model.getExtraProperties().containsKey("license") && model.getExtraProperties().get("license") != null) { Object license = model.getExtraProperties().get("license"); - HashMap licenseMap = jsonHandlingService.mapFromJson(jsonHandlingService.toJson(license)); + HashMap licenseMap = this.jsonHandlingService.mapFromJson(this.jsonHandlingService.toJson(license)); ReferenceEntity referenceEntity = new ReferenceEntity(); String licensePid; if (licenseMap.containsKey("pid") && licenseMap.get("pid") != null) { @@ -190,35 +197,59 @@ public class DmpMigrationService { continue; boolean licenseExists = collectedLicenses.contains(licensePid); if (!licenseExists) { + DefinitionEntity definitionEntity = new DefinitionEntity(); + List fields = new ArrayList<>(); if (licenseMap.containsKey("name")) { referenceEntity.setLabel(licenseMap.get("name")); } if (licenseMap.containsKey("uri")) { - referenceEntity.setSource(licenseMap.get("uri")); + referenceEntity.setReference(licenseMap.get("uri")); + if (!this.conventionService.isNullOrEmpty(licenseMap.get("uri"))){ + FieldEntity fieldEntity = new FieldEntity(); + fieldEntity.setCode("uri"); + fieldEntity.setDataType(ReferenceFieldDataType.Text); + fieldEntity.setValue(licenseMap.get("uri")); + fields.add(fieldEntity); + } + } + if (licenseMap.containsKey("tag")) { + if (!this.conventionService.isNullOrEmpty(licenseMap.get("tag"))){ + FieldEntity fieldEntity = new FieldEntity(); + fieldEntity.setCode("tag"); + fieldEntity.setDataType(ReferenceFieldDataType.Text); + fieldEntity.setValue(licenseMap.get("tag")); + fields.add(fieldEntity); + } + } + if (licenseMap.containsKey("hint")) { + if (!this.conventionService.isNullOrEmpty(licenseMap.get("hint"))){ + FieldEntity fieldEntity = new FieldEntity(); + fieldEntity.setCode("hint"); + fieldEntity.setDataType(ReferenceFieldDataType.Text); + fieldEntity.setValue(licenseMap.get("hint")); + fields.add(fieldEntity); + } } if (licenseMap.containsKey("abbreviation")) { referenceEntity.setAbbreviation(licenseMap.get("abbreviation")); } - if (licenseMap.containsKey("source") && licenseMap.get("source") != null) { - logger.debug("License found with source '{}'", licenseMap.get("source")); - } if (licenseMap.containsKey("created") && licenseMap.get("created") != null) { referenceEntity.setUpdatedAt(Instant.parse(licenseMap.get("created"))); } else { - referenceEntity.setCreatedAt(Instant.now()); + referenceEntity.setCreatedAt(item.getCreated() == null ? Instant.now() : item.getCreated().toInstant()); } if (licenseMap.containsKey("modified") && licenseMap.get("modified") != null) { referenceEntity.setUpdatedAt(Instant.parse(licenseMap.get("modified"))); } else { - referenceEntity.setUpdatedAt(Instant.now()); + referenceEntity.setUpdatedAt(item.getModified() == null ? Instant.now() : item.getModified().toInstant()); } -// if (licenseMap.containsKey("tag") && licenseMap.get("tag") != null && !"Open Definition".equals(licenseMap.get("tag"))) { -// logger.debug("License found with tag '{}'", licenseMap.get("tag")); -// } referenceEntity.setId(UUID.randomUUID()); referenceEntity.setSourceType(ReferenceSourceType.External); + referenceEntity.setSource(this.environment.getProperty("migration.default-license-source", "null")); referenceEntity.setType(ReferenceType.Licenses); referenceEntity.setIsActive(IsActive.Active); + definitionEntity.setFields(fields); + referenceEntity.setDefinition(this.xmlHandlingService.toXmlSafe(definitionEntity)); collectedLicenses.add(licensePid); licenseIdByName.put(licensePid, referenceEntity.getId()); diff --git a/dmp-migration-tool/web/src/main/resources/config/application.properties b/dmp-migration-tool/web/src/main/resources/config/application.properties index 2397efe84..898a39643 100644 --- a/dmp-migration-tool/web/src/main/resources/config/application.properties +++ b/dmp-migration-tool/web/src/main/resources/config/application.properties @@ -4,6 +4,7 @@ server.tomcat.max-connections = 10000 logging.file=/logs/spring-boot-logging.log spring.profiles.active=devel eu.eudat.logic.proxy.allowed.host=https://eestore.paas2.uninett.no +migration.default-license-source=opendefinition ####################Metrics############## management.endpoint.metrics.enabled=true From 35b0d58ec9f3f693a24b86d68d666bdd398a1d0a Mon Sep 17 00:00:00 2001 From: amentis Date: Tue, 19 Dec 2023 19:05:19 +0200 Subject: [PATCH 6/7] small changes in Notification Template --- .../enums/{DataType.java => NotificationDataType.java} | 8 ++++---- .../common/types/notification/FieldInfo.java | 10 +++++----- .../types/notificationtemplate/FieldInfoEntity.java | 10 +++++----- .../model/persist/NotificationTemplatePersist.java | 2 -- .../persist/notificationtemplate/FieldInfoPersist.java | 10 +++++----- .../notification/query/NotificationTemplateQuery.java | 2 +- .../message/infobuilder/MessageBuilderServiceImpl.java | 4 ++-- .../NotificationServiceTemplateImpl.java | 5 ++++- 8 files changed, 26 insertions(+), 25 deletions(-) rename dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/enums/{DataType.java => NotificationDataType.java} (61%) diff --git a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/enums/DataType.java b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/enums/NotificationDataType.java similarity index 61% rename from dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/enums/DataType.java rename to dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/enums/NotificationDataType.java index 82706d344..a0d9918b3 100644 --- a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/enums/DataType.java +++ b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/enums/NotificationDataType.java @@ -5,7 +5,7 @@ import gr.cite.notification.data.conventers.DatabaseEnum; import java.util.Map; -public enum DataType implements DatabaseEnum { +public enum NotificationDataType implements DatabaseEnum { Integer((short)0), Decimal((short)1), Double((short)2), @@ -14,7 +14,7 @@ public enum DataType implements DatabaseEnum { String((short)5); private final Short value; - DataType(Short value) { + NotificationDataType(Short value) { this.value = value; } @@ -23,9 +23,9 @@ public enum DataType implements DatabaseEnum { return value; } - private static final Map map = EnumUtils.getEnumValueMap(DataType.class); + private static final Map map = EnumUtils.getEnumValueMap(NotificationDataType.class); - public static DataType of(Short i) { + public static NotificationDataType of(Short i) { return map.get(i); } } diff --git a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/types/notification/FieldInfo.java b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/types/notification/FieldInfo.java index 69aa67529..b4c0ee47b 100644 --- a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/types/notification/FieldInfo.java +++ b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/types/notification/FieldInfo.java @@ -1,16 +1,16 @@ package gr.cite.notification.common.types.notification; -import gr.cite.notification.common.enums.DataType; +import gr.cite.notification.common.enums.NotificationDataType; public class FieldInfo { private String key; public final static String _key = "key"; - private DataType type; + private NotificationDataType type; public final static String _type = "type"; private String value; public final static String _value = "value"; - public FieldInfo(String key, DataType type, String value) { + public FieldInfo(String key, NotificationDataType type, String value) { this.key = key; this.type = type; this.value = value; @@ -27,11 +27,11 @@ public class FieldInfo { this.key = key; } - public DataType getType() { + public NotificationDataType getType() { return type; } - public void setType(DataType type) { + public void setType(NotificationDataType type) { this.type = type; } diff --git a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/types/notificationtemplate/FieldInfoEntity.java b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/types/notificationtemplate/FieldInfoEntity.java index 93e93bd9d..90afc8a87 100644 --- a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/types/notificationtemplate/FieldInfoEntity.java +++ b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/common/types/notificationtemplate/FieldInfoEntity.java @@ -1,13 +1,13 @@ package gr.cite.notification.common.types.notificationtemplate; -import gr.cite.notification.common.enums.DataType; +import gr.cite.notification.common.enums.NotificationDataType; public class FieldInfoEntity { private String key; - private DataType type; + private NotificationDataType type; private String value; - public FieldInfoEntity(String key, DataType type, String value) { + public FieldInfoEntity(String key, NotificationDataType type, String value) { this.key = key; this.type = type; this.value = value; @@ -24,11 +24,11 @@ public class FieldInfoEntity { this.key = key; } - public DataType getType() { + public NotificationDataType getType() { return type; } - public void setType(DataType type) { + public void setType(NotificationDataType type) { this.type = type; } diff --git a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/NotificationTemplatePersist.java b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/NotificationTemplatePersist.java index 71927dbad..81ba162b3 100644 --- a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/NotificationTemplatePersist.java +++ b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/NotificationTemplatePersist.java @@ -18,8 +18,6 @@ public class NotificationTemplatePersist { @ValidEnum private NotificationTemplateChannel channel; - @NotNull(message = "{validation.empty}") - @Valid private UUID notificationType; @ValidEnum diff --git a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/notificationtemplate/FieldInfoPersist.java b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/notificationtemplate/FieldInfoPersist.java index c61b8ae0b..26ef1a4a6 100644 --- a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/notificationtemplate/FieldInfoPersist.java +++ b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/model/persist/notificationtemplate/FieldInfoPersist.java @@ -1,6 +1,6 @@ package gr.cite.notification.model.persist.notificationtemplate; -import gr.cite.notification.common.enums.DataType; +import gr.cite.notification.common.enums.NotificationDataType; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @@ -13,13 +13,13 @@ public class FieldInfoPersist { @NotNull @NotEmpty - private DataType type; + private NotificationDataType type; @NotNull @NotEmpty private String value; - public FieldInfoPersist(String key, DataType type, String value) { + public FieldInfoPersist(String key, NotificationDataType type, String value) { this.key = key; this.type = type; this.value = value; @@ -36,11 +36,11 @@ public class FieldInfoPersist { this.key = key; } - public DataType getType() { + public NotificationDataType getType() { return type; } - public void setType(DataType type) { + public void setType(NotificationDataType type) { this.type = type; } diff --git a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationTemplateQuery.java b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationTemplateQuery.java index b06888c6b..bcffcd759 100644 --- a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationTemplateQuery.java +++ b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/query/NotificationTemplateQuery.java @@ -180,7 +180,7 @@ public class NotificationTemplateQuery extends QueryBase { FieldInfo fieldInfo = new FieldInfo(); fieldInfo.setKey(field.getKey()); - fieldInfo.setType(DataType.valueOf(field.getType())); + fieldInfo.setType(NotificationDataType.valueOf(field.getType())); fieldInfo.setValue(field.getValue()); return fieldInfo; }).collect(Collectors.toList())); diff --git a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/service/notificationtemplate/NotificationServiceTemplateImpl.java b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/service/notificationtemplate/NotificationServiceTemplateImpl.java index 3155d5759..0787f468b 100644 --- a/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/service/notificationtemplate/NotificationServiceTemplateImpl.java +++ b/dmp-backend/notification-service/notification/src/main/java/gr/cite/notification/service/notificationtemplate/NotificationServiceTemplateImpl.java @@ -92,16 +92,19 @@ public class NotificationServiceTemplateImpl implements NotificationTemplateServ data = this.entityManager.find(NotificationTemplateEntity.class, model.getId()); if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), NotificationTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale())); if (!this.conventionService.hashValue(data.getUpdatedAt()).equals(model.getHash())) throw new MyValidationException(this.errors.getHashConflict().getCode(), this.errors.getHashConflict().getMessage()); + if (model.getNotificationType() != null){ + data.setNotificationType(model.getNotificationType()); + } } else { data = new NotificationTemplateEntity(); data.setId(UUID.randomUUID()); data.setIsActive(IsActive.Active); data.setCreatedAt(Instant.now()); + data.setNotificationType(UUID.randomUUID()); } data.setChannel(model.getChannel()); data.setKind(model.getKind()); - data.setNotificationType(model.getNotificationType()); data.setLanguageId(model.getLanguageId()); data.setValue(this.jsonHandlingService.toJsonSafe(this.buildNotificationTemplateValueEntity(model.getValue()))); data.setUpdatedAt(Instant.now()); From b3b619d3542016542802bbe8088a6382143fa2fb Mon Sep 17 00:00:00 2001 From: amentis Date: Tue, 19 Dec 2023 19:08:17 +0200 Subject: [PATCH 7/7] add UI Notification Template --- dmp-frontend/src/app/app-routing.module.ts | 12 + .../core/common/enum/email-override-mode.ts | 5 + .../common/enum/notification-data-type.ts | 7 + .../enum/notification-template-channel.ts | 4 + .../common/enum/notification-template-kind.ts | 6 + .../app/core/common/enum/permission.enum.ts | 6 + .../src/app/core/core-service.module.ts | 4 +- .../notification-template.ts | 80 ++++ .../query/notification-template.lookup.ts | 25 ++ .../notification-template.service.ts | 60 +++ .../services/utilities/enum-utils.service.ts | 38 ++ ...otification-template-editor.component.html | 345 +++++++++++++++++ ...otification-template-editor.component.scss | 43 +++ .../notification-template-editor.component.ts | 350 ++++++++++++++++++ .../notification-template-editor.model.ts | 289 +++++++++++++++ .../notification-template-editor.resolver.ts | 44 +++ .../notification-template-editor.service.ts | 15 + ...on-template-listing-filters.component.html | 36 ++ ...on-template-listing-filters.component.scss | 25 ++ ...tion-template-listing-filters.component.ts | 91 +++++ ...tification-template-listing.component.html | 95 +++++ ...tification-template-listing.component.scss | 60 +++ ...notification-template-listing.component.ts | 175 +++++++++ .../notification-template.module.ts | 43 +++ .../notification-template.routing.ts | 58 +++ .../src/app/ui/sidebar/sidebar.component.ts | 3 +- dmp-frontend/src/assets/i18n/en.json | 96 ++++- 27 files changed, 2011 insertions(+), 4 deletions(-) create mode 100644 dmp-frontend/src/app/core/common/enum/email-override-mode.ts create mode 100644 dmp-frontend/src/app/core/common/enum/notification-data-type.ts create mode 100644 dmp-frontend/src/app/core/common/enum/notification-template-channel.ts create mode 100644 dmp-frontend/src/app/core/common/enum/notification-template-kind.ts create mode 100644 dmp-frontend/src/app/core/model/notification-template/notification-template.ts create mode 100644 dmp-frontend/src/app/core/query/notification-template.lookup.ts create mode 100644 dmp-frontend/src/app/core/services/notification-template/notification-template.service.ts create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.html create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.scss create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.ts create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.model.ts create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.resolver.ts create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.service.ts create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.html create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.scss create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.ts create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.html create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.scss create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.ts create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/notification-template.module.ts create mode 100644 dmp-frontend/src/app/ui/admin/notification-template/notification-template.routing.ts diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts index c8c054f8d..6a6f50247 100644 --- a/dmp-frontend/src/app/app-routing.module.ts +++ b/dmp-frontend/src/app/app-routing.module.ts @@ -295,6 +295,18 @@ const appRoutes: Routes = [ }) }, }, + { + path: 'notification-templates', + loadChildren: () => import('./ui/admin/notification-template/notification-template.module').then(m => m.NotificationTemplateModule), + data: { + authContext: { + permissions: [AppPermission.ViewNotificationTemplatePage] + }, + ...BreadcrumbService.generateRouteDataConfiguration({ + title: 'BREADCRUMBS.NOTIFICATION-TEMPLATES' + }) + }, + }, { path: 'index-managment', loadChildren: () => import('./ui/admin/index-managment/index-managment.module').then(m => m.IndexManagmentModule), diff --git a/dmp-frontend/src/app/core/common/enum/email-override-mode.ts b/dmp-frontend/src/app/core/common/enum/email-override-mode.ts new file mode 100644 index 000000000..45391e9b3 --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/email-override-mode.ts @@ -0,0 +1,5 @@ +export enum EmailOverrideMode { + NotOverride = 0, + Additive = 1, + Replace = 2 +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/common/enum/notification-data-type.ts b/dmp-frontend/src/app/core/common/enum/notification-data-type.ts new file mode 100644 index 000000000..249e92573 --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/notification-data-type.ts @@ -0,0 +1,7 @@ +export enum NotificationDataType { + Integer = 0, + Demical = 1, + Double = 2, + DateTime = 3, + String = 5 +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/common/enum/notification-template-channel.ts b/dmp-frontend/src/app/core/common/enum/notification-template-channel.ts new file mode 100644 index 000000000..b4f328a34 --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/notification-template-channel.ts @@ -0,0 +1,4 @@ +export enum NotificationTemplateChannel { + Email = 0, + InApp = 1, +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/common/enum/notification-template-kind.ts b/dmp-frontend/src/app/core/common/enum/notification-template-kind.ts new file mode 100644 index 000000000..ec0e8a47e --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/notification-template-kind.ts @@ -0,0 +1,6 @@ +export enum NotificationTemplateKind { + Draft = 0, + Secondary = 1, + Primary = 2, + Default = 3 +} diff --git a/dmp-frontend/src/app/core/common/enum/permission.enum.ts b/dmp-frontend/src/app/core/common/enum/permission.enum.ts index e3b7fb10a..cd71ed394 100644 --- a/dmp-frontend/src/app/core/common/enum/permission.enum.ts +++ b/dmp-frontend/src/app/core/common/enum/permission.enum.ts @@ -28,6 +28,7 @@ export enum AppPermission { ViewReferencePage = 'ViewReferencePage', ViewTenantPage = 'ViewTenantPage', ViewLanguagePage = "ViewLanguagePage", + ViewNotificationTemplatePage = "ViewNotificationTemplatePage", //ReferenceType BrowseReferenceType = "BrowseReferenceType", @@ -54,5 +55,10 @@ export enum AppPermission { BrowseLanguage = "BrowseLanguage", EditLanguage = "EditLanguage", DeleteLanguage = "DeleteLanguage", + + //Notification Template + BrowseNotificationTemplate = "BrowseNotificationTemplate", + EditNotificationTemplate = "EditNotificationTemplate", + DeleteNotificationTemplate = "DeleteNotificationTemplate", } diff --git a/dmp-frontend/src/app/core/core-service.module.ts b/dmp-frontend/src/app/core/core-service.module.ts index deca49579..9e6ae0795 100644 --- a/dmp-frontend/src/app/core/core-service.module.ts +++ b/dmp-frontend/src/app/core/core-service.module.ts @@ -64,6 +64,7 @@ import { QueryParamsService } from './services/utilities/query-params.service'; import { LanguageHttpService } from './services/language/language.http.service'; import { DescriptionService } from './services/description/description.service'; import { MaintenanceService } from './services/maintenance/maintenance.service'; +import { NotificationTemplateService } from './services/notification-template/notification-template.service'; // // // This is shared module that provides all the services. Its imported only once on the AppModule. @@ -147,7 +148,8 @@ export class CoreServiceModule { LanguageHttpService, DmpServiceNew, DescriptionService, - MaintenanceService + MaintenanceService, + NotificationTemplateService ], }; } diff --git a/dmp-frontend/src/app/core/model/notification-template/notification-template.ts b/dmp-frontend/src/app/core/model/notification-template/notification-template.ts new file mode 100644 index 000000000..c59c0e924 --- /dev/null +++ b/dmp-frontend/src/app/core/model/notification-template/notification-template.ts @@ -0,0 +1,80 @@ +import { NotificationTemplateChannel } from "@app/core/common/enum/notification-template-channel"; +import { NotificationTemplateKind } from "@app/core/common/enum/notification-template-kind"; +import { BaseEntity, BaseEntityPersist } from "@common/base/base-entity.model"; +import { Guid } from "@common/types/guid"; +import { Language } from "../language/language"; +import { NotificationDataType } from "@app/core/common/enum/notification-data-type"; +import { EmailOverrideMode } from "@app/core/common/enum/email-override-mode"; + +export interface NotificationTemplate extends BaseEntity{ + channel: NotificationTemplateChannel; + notificationType: Guid; + kind: NotificationTemplateKind; + language: Language; + value: NotificationTemplateValue; +} + +export interface NotificationTemplateValue { + subjectText: string; + subjectKey: string; + subjectFieldOptions: NotificationFieldOptions; + bodyText: string; + bodyKey: string; + priorityKey: string; + allowAttachments: Boolean; + cc: string[]; + ccMode: EmailOverrideMode; + bcc: string[]; + bccMode: EmailOverrideMode; + extraDataKeys: string[]; + bodyFieldOptions: NotificationFieldOptions; +} + +export interface NotificationFieldOptions { + mandatory?: string[]; + options?: NotificationFieldInfo[]; + formatting?: { [key: string]: string }; +} + +export interface NotificationFieldInfo { + key: string; + dataType: NotificationDataType, + value: string; +} + +// Persist + +export interface NotificationTemplatePersist extends BaseEntityPersist{ + channel: NotificationTemplateChannel; + kind: NotificationTemplateKind; + languageId: Guid; + value: NotificationTemplateValuePersist; +} + +export interface NotificationTemplateValuePersist { + subjectText: string; + subjectKey: string; + subjectFieldOptions: NotificationFieldOptionsPersist; + bodyText: string; + bodyKey: string; + priorityKey: string; + allowAttachments: Boolean; + cc: string[]; + ccMode: EmailOverrideMode; + bcc: string[]; + bccMode: EmailOverrideMode; + extraDataKeys: string[]; + bodyFieldOptions: NotificationFieldOptionsPersist; +} + +export interface NotificationFieldOptionsPersist { + mandatory?: string[]; + options?: NotificationFieldInfoPersist[]; + formatting?: { [key: string]: string }; +} + +export interface NotificationFieldInfoPersist { + key: string; + dataType: NotificationDataType, + value: string; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/query/notification-template.lookup.ts b/dmp-frontend/src/app/core/query/notification-template.lookup.ts new file mode 100644 index 000000000..6d24e6be8 --- /dev/null +++ b/dmp-frontend/src/app/core/query/notification-template.lookup.ts @@ -0,0 +1,25 @@ +import { Lookup } from "@common/model/lookup"; +import { Guid } from "@common/types/guid"; +import { IsActive } from "../common/enum/is-active.enum"; +import { NotificationTemplateKind } from "../common/enum/notification-template-kind"; +import { NotificationTemplateChannel } from "../common/enum/notification-template-channel"; + +export class NotificationTemplateLookup extends Lookup implements NotificationTemplateFilter { + ids: Guid[]; + excludedIds: Guid[]; + isActive: IsActive[]; + kinds: NotificationTemplateKind[]; + channels: NotificationTemplateChannel[]; + + constructor() { + super(); + } +} + +export interface NotificationTemplateFilter { + ids: Guid[]; + excludedIds: Guid[]; + isActive: IsActive[]; + kinds: NotificationTemplateKind[]; + channels: NotificationTemplateChannel[]; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/notification-template/notification-template.service.ts b/dmp-frontend/src/app/core/services/notification-template/notification-template.service.ts new file mode 100644 index 000000000..c82dcb395 --- /dev/null +++ b/dmp-frontend/src/app/core/services/notification-template/notification-template.service.ts @@ -0,0 +1,60 @@ +import { Injectable } from '@angular/core'; +import { QueryResult } from '@common/model/query-result'; +import { Guid } from '@common/types/guid'; +import { NotificationTemplateKind } from '@app/core/common/enum/notification-template-kind'; +import { NotificationTemplateLookup } from '@app/core/query/notification-template.lookup'; +import { Observable, throwError } from 'rxjs'; +import { catchError } from 'rxjs/operators'; +import { NotificationTemplate, NotificationTemplatePersist } from '@app/core/model/notification-template/notification-template'; +import { BaseHttpV2Service } from '../http/base-http-v2.service'; + +@Injectable() +export class NotificationTemplateService { + + constructor(private http: BaseHttpV2Service) { + } + + //TODO ADD CONIFG URL + private get apiBase(): string { return `http://localhost:8081/api/notification-template`; } + + query(q: NotificationTemplateLookup): 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))); + } + + updateKind(id: Guid, kind: NotificationTemplateKind): Observable { + const url = `${this.apiBase}/${id}/${kind}`; + + return this.http + .post(url, {}).pipe( + catchError((error: any) => throwError(error))); + } + + persist(item: NotificationTemplatePersist): 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))); + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts index be8df9173..5b3c35f56 100644 --- a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts +++ b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts @@ -28,6 +28,10 @@ import { DmpStatus } from '../../common/enum/dmp-status'; import { ValidationType } from '../../common/enum/validation-type'; import { IsActive } from '@app/core/common/enum/is-active.enum'; import { DmpUserRole } from '@app/core/common/enum/dmp-user-role'; +import { NotificationTemplateKind } from '@app/core/common/enum/notification-template-kind'; +import { NotificationTemplateChannel } from '@app/core/common/enum/notification-template-channel'; +import { NotificationDataType } from '@app/core/common/enum/notification-data-type'; +import { EmailOverrideMode } from '@app/core/common/enum/email-override-mode'; @Injectable() export class EnumUtils { @@ -376,4 +380,38 @@ export class EnumUtils { case DmpUserRole.User: return this.language.instant('TYPES.DMP-USER-ROLE.USER'); } } + + toNotificationTemplateKindString(status: NotificationTemplateKind): string { + switch (status) { + case NotificationTemplateKind.Draft: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-KIND.DRAFT'); + case NotificationTemplateKind.Secondary: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-KIND.SECONDARY'); + case NotificationTemplateKind.Primary: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-KIND.PRIMARY'); + case NotificationTemplateKind.Default: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-KIND.DEFAULT'); + } + } + + toNotificationTemplateChannelString(status: NotificationTemplateChannel): string { + switch (status) { + case NotificationTemplateChannel.Email: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-CHANNEL.EMAIL'); + case NotificationTemplateChannel.InApp: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-CHANNEL.INAPP'); + } + } + + toNotificationTemplateDataTypeString(status: NotificationDataType): string { + switch (status) { + case NotificationDataType.Integer: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-DATA-TYPE.INTEGER'); + case NotificationDataType.Demical: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-DATA-TYPE.DEMICAL'); + case NotificationDataType.Double: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-DATA-TYPE.DOUBLE'); + case NotificationDataType.DateTime: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-DATA-TYPE.DATE-TIME'); + case NotificationDataType.String: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-DATA-TYPE.STRING'); + } + } + + toEmailOverrideModeString(status: EmailOverrideMode): string { + switch (status) { + case EmailOverrideMode.NotOverride: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-EMAIL-OVERRIDE-MODE.NOT'); + case EmailOverrideMode.Additive: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-EMAIL-OVERRIDE-MODE.ADDITIVE'); + case EmailOverrideMode.Replace: return this.language.instant('TYPES.NOTIFICATION-TEMPLATE-EMAIL-OVERRIDE-MODE.REPLACE'); + } + } } diff --git a/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.html b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.html new file mode 100644 index 000000000..bb98a6ec8 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.html @@ -0,0 +1,345 @@ +
+
+ +
+
+

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.NEW' | translate}}

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ + + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.NEW' | translate}} + + +
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.LANGUAGE' | translate}} + + + {{languageCode}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KIND' | translate}} + + + {{enumUtils.toNotificationTemplateKindString(kind)}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.CHANNEL' | translate}} + + + {{enumUtils.toNotificationTemplateChannelString(channel)}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + +
+

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-SECTION' | translate}}

+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-TEXT' | translate}} + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-KEY' | translate}} + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+
+

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.SUBJECT-FIELD-OPTIONS' | translate}} + +

+
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.MANDATORY' | translate}} + + + {{field}} + + + + + +
+

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.OPTIONAL-TITLE' | translate}}

+
+
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KEY' | translate}} + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.DATA-TYPE' | translate}} + + + {{enumUtils.toNotificationTemplateDataTypeString(type)}} + + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.VALUE' | translate}} + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+ +
+
+
+
+
+ +
+
+
+
+ + +
+

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-SECTION' | translate}}

+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-TEXT' | translate}} + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-KEY' | translate}} + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+
+

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BODY-FIELD-OPTIONS' | translate}} + +

+
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.MANDATORY' | translate}} + + + {{field}} + + + + + +
+

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.OPTIONAL-TITLE' | translate}}

+
+
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.KEY' | translate}} + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.DATA-TYPE' | translate}} + + + {{enumUtils.toNotificationTemplateDataTypeString(type)}} + + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.VALUE' | translate}} + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+ +
+
+
+
+
+ +
+
+
+
+ +
+

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.EXTRA-OPTIONS' | translate}}

+
+

{{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.ALLOW-ATTACHMENTS' | translate}} + +

+
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.PRIORITY-KEY' | translate}} + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.CC' | translate}} + + + {{field}} + + + + + +
+
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.CC-MODE' | translate}} + + + {{enumUtils.toEmailOverrideModeString(emailOverrideMode)}} + + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+
+ +
+ + {{'NOTIFICATION-SERVICE.NOTIFICATION-TEMPLATE-EDITOR.FIELDS.BCC-MODE' | translate}} + + + {{enumUtils.toEmailOverrideModeString(emailOverrideMode)}} + + + {{'COMMONS.VALIDATION.REQUIRED' | translate}} + +
+ + +
+
+
+ +
+
+ diff --git a/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.scss b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.scss new file mode 100644 index 000000000..60e3c667a --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.scss @@ -0,0 +1,43 @@ +.notification-template-editor { + margin-top: 1.3rem; + margin-left: 1em; + margin-right: 3em; + + .remove { + background-color: white; + color: black; + } + + .add { + background-color: white; + color: #009700; + } + } + + ::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background, .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background { + background-color: var(--primary-color-3); + // background-color: #0070c0; + } + + ::ng-deep .mat-checkbox-disabled.mat-checkbox-checked .mat-checkbox-background, .mat-checkbox-disabled.mat-checkbox-indeterminate .mat-checkbox-background { + background-color: #b0b0b0; + } + + .action-btn { + border-radius: 30px; + background-color: var(--secondary-color); + border: 1px solid transparent; + padding-left: 2em; + padding-right: 2em; + box-shadow: 0px 3px 6px #1E202029; + + transition-property: background-color, color; + transition-duration: 200ms; + transition-delay: 50ms; + transition-timing-function: ease-in-out; + &:disabled{ + background-color: #CBCBCB; + color: #FFF; + border: 0px; + } + } diff --git a/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.ts b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.ts new file mode 100644 index 000000000..6d1c7b937 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.component.ts @@ -0,0 +1,350 @@ +import { Component, OnInit } from '@angular/core'; +import { FormArray, UntypedFormGroup } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { FormService } from '@common/forms/form-service'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { TranslateService } from '@ngx-translate/core'; +import { NotificationTemplateKind } from '@app/core/common/enum/notification-template-kind'; +import { AppPermission } from '@app/core/common/enum/permission.enum'; +import { NotificationTemplate, NotificationTemplatePersist } from '@app/core/model/notification-template/notification-template'; +import { NotificationTemplateService } from '@app/core/services/notification-template/notification-template.service'; +import { NotificationFieldInfoEditorModel, NotificationFieldOptionsEditorModel, NotificationTemplateEditorModel } from './notification-template-editor.model'; +import { map, takeUntil } from 'rxjs/operators'; +import { BaseEditor } from '@common/base/base-editor'; +import { ActivatedRoute, Router } from '@angular/router'; +import { FilterService } from '@common/modules/text-filter/filter-service'; +import { DatePipe } from '@angular/common'; +import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; +import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { NotificationTemplateEditorService } from './notification-template-editor.service'; +import { Guid } from '@common/types/guid'; +import { NotificationTemplateEditorResolver } from './notification-template-editor.resolver'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { LoggingService } from '@app/core/services/logging/logging-service'; +import { LanguageHttpService } from '@app/core/services/language/language.http.service'; +import { Language } from '@app/core/model/language/language'; +import { nameof } from 'ts-simple-nameof'; +import { NotificationTemplateChannel } from '@app/core/common/enum/notification-template-channel'; +import { MatChipEditedEvent, MatChipInputEvent } from '@angular/material/chips'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { NotificationDataType } from '@app/core/common/enum/notification-data-type'; +import { EmailOverrideMode } from '@app/core/common/enum/email-override-mode'; + +@Component({ + selector: 'app-notification-template-editor', + templateUrl: './notification-template-editor.component.html', + styleUrls: ['./notification-template-editor.component.scss'], + providers: [NotificationTemplateEditorService] +}) +export class NotificationTemplateEditorComponent extends BaseEditor implements OnInit { + + isNew = true; + isDeleted = false; + formGroup: UntypedFormGroup = null; + availableLanguageCodes: string[] = []; + selectedLangId: Guid = null; + subjectMandatoryFields: string[] = []; + bodyMandatoryFields: string[] = []; + subjectFieldOptionsEnabled: Boolean = false; + bodyFieldOptionsEnabled: Boolean = false; + ccValues: string[] = []; + bccValues: string[] = []; + extraDataKeys: string[] = []; + public notificationTemplateKindEnum = this.enumUtils.getEnumValues(NotificationTemplateKind); + public notificationTemplateChannelEnum = this.enumUtils.getEnumValues(NotificationTemplateChannel); + public notificationDataTypeEnum = this.enumUtils.getEnumValues(NotificationDataType); + public emailOverrideModeEnum = this.enumUtils.getEnumValues(EmailOverrideMode); + + protected get canDelete(): boolean { + return !this.isDeleted && !this.isNew && this.hasPermission(this.authService.permissionEnum.DeleteNotificationTemplate); + } + + protected get canSave(): boolean { + return !this.isDeleted && this.hasPermission(this.authService.permissionEnum.EditNotificationTemplate); + } + + private hasPermission(permission: AppPermission): boolean { + return this.authService.hasPermission(permission) || this.editorModel?.permissions?.includes(permission); + } + + constructor( + // BaseFormEditor injected dependencies + protected dialog: MatDialog, + protected language: TranslateService, + protected formService: FormService, + protected router: Router, + protected uiNotificationService: UiNotificationService, + protected httpErrorHandlingService: HttpErrorHandlingService, + protected filterService: FilterService, + protected datePipe: DatePipe, + protected route: ActivatedRoute, + protected queryParamsService: QueryParamsService, + // Rest dependencies. Inject any other needed deps here: + public authService: AuthService, + public enumUtils: EnumUtils, + private languageHttpService: LanguageHttpService, + private notificationTemplateService: NotificationTemplateService, + private notificationTemplateEditorService: NotificationTemplateEditorService, + private logger: LoggingService, + private matomoService: MatomoService + ) { + super(dialog, language, formService, router, uiNotificationService, httpErrorHandlingService, filterService, datePipe, route, queryParamsService); + } + + // ngOnInit(): void { + // this.editorModel = new NotificationTemplateEditorModel().fromModel(this.notificationTemplate); + // this.formGroup = this.editorModel.buildForm(null, this.editorModel.kind === NotificationTemplateKind.Default ? true : !this.authService.permissionEnum.EditDescription); + // } + + ngOnInit(): void { + this.matomoService.trackPageView('Admin: Notification Tempplates'); + super.ngOnInit(); + this.languageHttpService.queryAvailableCodes(this.languageHttpService.buildAutocompleteLookup()) + .pipe(takeUntil(this._destroyed)) + .subscribe( + data => this.availableLanguageCodes = data.items, + ); + } + + getItem(itemId: Guid, successFunction: (item: NotificationTemplate) => void) { + this.notificationTemplateService.getSingle(itemId, NotificationTemplateEditorResolver.lookupFields()) + .pipe(map(data => data as NotificationTemplate), takeUntil(this._destroyed)) + .subscribe( + data => successFunction(data), + error => this.onCallbackError(error) + ); + } + + prepareForm(data: NotificationTemplate) { + try { + this.editorModel = data ? new NotificationTemplateEditorModel().fromModel(data) : new NotificationTemplateEditorModel(); + + if(data){ + if(data.value && data.value.subjectFieldOptions){ + this.subjectFieldOptionsEnabled = true; + } + } + this.isDeleted = data ? data.isActive === IsActive.Inactive : false; + this.buildForm(); + } catch (error) { + this.logger.error('Could not parse Tenant item: ' + data + error); + this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error); + } + } + + buildForm() { + this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.authService.hasPermission(AppPermission.EditNotificationTemplate)); + this.notificationTemplateEditorService.setValidationErrorModel(this.editorModel.validationErrorModel); + } + + refreshData(): void { + this.getItem(this.editorModel.id, (data: NotificationTemplate) => this.prepareForm(data)); + } + + refreshOnNavigateToData(id?: Guid): void { + this.formGroup.markAsPristine(); + let route = []; + + if (id === null) { + route.push('../..'); + } else if (this.isNew) { + route.push('../' + id); + } else { + route.push('..'); + } + + this.router.navigate(route, { queryParams: { 'lookup': this.queryParamsService.serializeLookup(this.lookupParams), 'lv': ++this.lv }, replaceUrl: true, relativeTo: this.route }); + } + + persistEntity(onSuccess?: (response) => void): void { + const formData = this.formService.getValue(this.formGroup.value) as NotificationTemplatePersist; + + this.notificationTemplateService.persist(formData) + .pipe(takeUntil(this._destroyed)).subscribe( + complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete), + error => this.onCallbackError(error) + ); + } + + formSubmit(): void { + this.formService.touchAllFormFields(this.formGroup); + if (!this.isFormValid()) { + return; + } + + this.persistEntity(); + } + + public delete() { + const value = this.formGroup.value; + if (value.id) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '300px', + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.notificationTemplateService.delete(value.id).pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(), + error => this.onCallbackError(error) + ); + } + }); + } + } + + clearErrorModel() { + this.editorModel.validationErrorModel.clear(); + this.formService.validateAllFormFields(this.formGroup); + } + + selectedLangChanged(code: string){ + + this.languageHttpService.getSingleWithCode(code, [nameof(x => x.id),nameof(x => x.code)]) + .pipe(takeUntil(this._destroyed)) + .subscribe( + data => { + this.selectedLangId = data.id + console.log(this.formGroup);} + ); + } + + + subjectFieldOptionsSelectionChanged(matCheckBox: MatCheckboxChange){ + if(matCheckBox.checked == true){ + this.subjectFieldOptionsEnabled = true; + }else{ + this.subjectFieldOptionsEnabled = false; + } + } + + bodyFieldOptionsSelectionChanged(matCheckBox: MatCheckboxChange){ + if(matCheckBox.checked == true){ + this.bodyFieldOptionsEnabled = true; + }else{ + this.bodyFieldOptionsEnabled = false; + } + } + + // subject mandatory + + addSubjectMandatory(event: MatChipInputEvent): void { + const value = (event.value || '').trim(); + + if (value) this.subjectMandatoryFields.push(value) + event.chipInput!.clear(); + } + + removeSubjectMandatory(field: string): void { + const index = this.subjectMandatoryFields.indexOf(field); + + if (index >= 0) this.subjectMandatoryFields.splice(index, 1); + } + + editSubjectMandatory(field: string, event: MatChipEditedEvent) { + const value = event.value.trim(); + + if (!value) { + this.removeSubjectMandatory(field); + return; + } + + const index = this.subjectMandatoryFields.indexOf(field); + if (index >= 0) this.subjectMandatoryFields[index] = value + } + + // chip lists + + addChipListValues(type: string, event: MatChipInputEvent){ + if(type == "cc"){ + this.ccValues = this.add(event, this.ccValues); + }else if(type == "bcc"){ + this.bccValues = this.add(event, this.bccValues); + }else if(type == "extraDataKeys"){ + this.extraDataKeys = this.add(event, this.extraDataKeys); + }else if(type == "subject"){ + this.subjectMandatoryFields = this.add(event, this.subjectMandatoryFields); + }else if(type == "body"){ + this.bodyMandatoryFields = this.add(event, this.bodyMandatoryFields); + } + } + + editChipListValues(type: string, event: MatChipEditedEvent, field: string){ + if(type == "cc"){ + this.ccValues = this.edit(field, this.ccValues, event); + }else if(type == "bcc"){ + this.bccValues = this.edit(field, this.bccValues, event); + }else if(type == "extraDataKeys"){ + this.extraDataKeys = this.edit(field, this.extraDataKeys, event); + }else if(type == "subject"){ + this.subjectMandatoryFields = this.edit(field, this.subjectMandatoryFields, event); + }else if(type == "body"){ + this.bodyMandatoryFields = this.edit(field, this.bodyMandatoryFields, event); + } + } + + removeChipListValues(type: string, field: string){ + if(type == "cc"){ + this.ccValues = this.remove(field, this.ccValues); + }else if(type == "bcc"){ + this.bccValues = this.remove(field, this.bccValues); + }else if(type == "extraDataKeys"){ + this.extraDataKeys = this.remove(field, this.extraDataKeys); + }else if(type == "subject"){ + this.subjectMandatoryFields = this.remove(field, this.subjectMandatoryFields); + }else if(type == "body"){ + this.bodyMandatoryFields = this.remove(field, this.bodyMandatoryFields); + } + } + + add(event: MatChipInputEvent, values: string[]) { + const value = (event.value || '').trim(); + + if (value) values.push(value) + event.chipInput!.clear(); + return values; + + } + + remove(field: string, values: string[]) { + const index = values.indexOf(field); + + if (index >= 0) values.splice(index, 1); + return values; + } + + edit(field: string, values: string[], event: MatChipEditedEvent) { + const value = event.value.trim(); + + if (!value) { + values = this.remove(field, values); + return values; + } + + const index = values.indexOf(field); + if (index >= 0) values[index] = value + + return values; + } + + //options fields + + addOptionalItem(formGroup: UntypedFormGroup) { + const fieldInfo: NotificationFieldInfoEditorModel = new NotificationFieldInfoEditorModel(); + (formGroup.get('options') as FormArray).push(fieldInfo.buildForm()); + } + + removeOptionalItem(formGroup: UntypedFormGroup, optionalIndex: number): void { + (formGroup.get('options') as FormArray).removeAt(optionalIndex); + } + +} diff --git a/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.model.ts b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.model.ts new file mode 100644 index 000000000..1971718f4 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.model.ts @@ -0,0 +1,289 @@ +import { FormArray, FormControl, UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { NotificationFieldInfo, NotificationFieldInfoPersist, NotificationFieldOptions, NotificationFieldOptionsPersist, NotificationTemplate, NotificationTemplatePersist, NotificationTemplateValue, NotificationTemplateValuePersist } from '@app/core/model/notification-template/notification-template'; +import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; +import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; +import { Validation, ValidationContext } from '@common/forms/validation/validation-context'; +import { Guid } from '@common/types/guid'; +import { NotificationTemplateChannel } from '@app/core/common/enum/notification-template-channel'; +import { NotificationTemplateKind } from '@app/core/common/enum/notification-template-kind'; +import { NotificationDataType } from '@app/core/common/enum/notification-data-type'; +import { EmailOverrideMode } from '@app/core/common/enum/email-override-mode'; +import { BaseEditorModel } from '@common/base/base-form-editor-model'; + +export class NotificationTemplateEditorModel extends BaseEditorModel implements NotificationTemplatePersist { + channel: NotificationTemplateChannel; + notificationType: Guid; + kind: NotificationTemplateKind; + languageId: Guid; + value: NotificationTemplateValueEditorModel = new NotificationTemplateValueEditorModel(); + permissions: string[]; + + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor() { super();} + + public fromModel(item: NotificationTemplate): NotificationTemplateEditorModel { + if(item){ + super.fromModel(item); + this.channel = item.channel; + this.notificationType = item.notificationType; + this.kind = item.kind; + if(item.language) //TODO this.language = item.language; + if (item.value) { this.value = new NotificationTemplateValueEditorModel().fromModel(item.value); } + } + + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): UntypedFormGroup { + if (context == null) { context = this.createValidationContext(); } + + return this.formBuilder.group({ + id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators], + channel: [{ value: this.channel, disabled: disabled }, context.getValidation('channel').validators], + notificationType: [{ value: this.notificationType, disabled: disabled }, context.getValidation('notificationType').validators], + kind: [{ value: this.kind, disabled: disabled }, context.getValidation('kind').validators], + language: [{ value: this.languageId, disabled: disabled }, context.getValidation('language').validators], + value: this.value.buildForm({ + rootPath: `value.` + }), + hash: [{ value: this.hash, disabled: disabled }, context.getValidation('hash').validators], + }); + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] }); + baseValidationArray.push({ key: 'channel', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'channel')] }); + baseValidationArray.push({ key: 'notificationType', validators: [BackendErrorValidator(this.validationErrorModel, 'notificationType')] }); + baseValidationArray.push({ key: 'kind', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'kind')] }); + baseValidationArray.push({ key: 'language', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'language')] }); + baseValidationArray.push({ key: 'value', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'value')] }); + baseValidationArray.push({ key: 'hash', validators: [] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } +} + +export class NotificationTemplateValueEditorModel implements NotificationTemplateValuePersist { + subjectText: string; + subjectKey: string; + subjectFieldOptions: NotificationFieldOptionsEditorModel = new NotificationFieldOptionsEditorModel(); + bodyText: string; + bodyKey: string; + priorityKey: string; + allowAttachments: Boolean = false; + cc: string[] = []; + ccMode: EmailOverrideMode; + bcc: string[] = []; + bccMode: EmailOverrideMode; + extraDataKeys: string[] = []; + bodyFieldOptions: NotificationFieldOptionsEditorModel = new NotificationFieldOptionsEditorModel(); + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + public fromModel(item: NotificationTemplateValue): NotificationTemplateValueEditorModel { + if (item) { + this.subjectText = item.subjectText; + this.subjectKey = item.subjectKey; + if (item.subjectFieldOptions) this.subjectFieldOptions = new NotificationFieldOptionsEditorModel().fromModel(item.subjectFieldOptions); + this.bodyText = item.bodyText; + this.bodyKey = item.bodyKey; + this.priorityKey = item.priorityKey; + this.allowAttachments = item.allowAttachments; + this.cc = item.cc; + this.ccMode = item.ccMode; + this.bcc = item.bcc; + this.bccMode = item.bccMode; + this.extraDataKeys = item.extraDataKeys; + if (item.bodyFieldOptions) this.bodyFieldOptions = new NotificationFieldOptionsEditorModel().fromModel(item.bodyFieldOptions); + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = NotificationTemplateValueEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + return this.formBuilder.group({ + subjectText: [{ value: this.subjectText, disabled: disabled }, context.getValidation('subjectText').validators], + subjectKey: [{ value: this.subjectKey, disabled: disabled }, context.getValidation('subjectKey').validators], + subjectFieldOptions: this.subjectFieldOptions.buildForm({ + rootPath: `subjectFieldOptions.` + }), + bodyText: [{ value: this.bodyText, disabled: disabled }, context.getValidation('bodyText').validators], + bodyKey: [{ value: this.bodyKey, disabled: disabled }, context.getValidation('bodyKey').validators], + priorityKey: [{ value: this.priorityKey, disabled: disabled }, context.getValidation('priorityKey').validators], + allowAttachments: [{ value: this.allowAttachments, disabled: disabled }, context.getValidation('allowAttachments').validators], + cc: [{ value: this.cc, disabled: disabled }, context.getValidation('cc').validators], + ccMode: [{ value: this.ccMode, disabled: disabled }, context.getValidation('ccMode').validators], + bcc: [{ value: this.bcc, disabled: disabled }, context.getValidation('bcc').validators], + bccMode: [{ value: this.bccMode, disabled: disabled }, context.getValidation('bccMode').validators], + extraDataKeys: [{ value: this.extraDataKeys, disabled: disabled }, context.getValidation('extraDataKeys').validators], + bodyFieldOptions: this.bodyFieldOptions.buildForm({ + rootPath: `bodyFieldOptions.` + }), + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'subjectText', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}subjectText`)] }); + baseValidationArray.push({ key: 'subjectKey', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}subjectKey`)] }); + baseValidationArray.push({ key: 'bodyText', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}bodyText`)] }); + baseValidationArray.push({ key: 'bodyKey', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}bodyKey`)] }); + baseValidationArray.push({ key: 'priorityKey', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}priorityKey`)] }); + baseValidationArray.push({ key: 'allowAttachments', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}allowAttachments`)] }); + baseValidationArray.push({ key: 'cc', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}cc`)] }); + baseValidationArray.push({ key: 'ccMode', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}ccMode`)] }); + baseValidationArray.push({ key: 'bcc', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}bcc`)] }); + baseValidationArray.push({ key: 'bccMode', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}bccMode`)] }); + baseValidationArray.push({ key: 'extraDataKeys', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}extraDataKeys`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } +} + +export class NotificationFieldOptionsEditorModel implements NotificationFieldOptionsPersist { + mandatory?: string[] = []; + options?: NotificationFieldInfoEditorModel[] = []; + formatting?: { [key: string]: string }; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + public fromModel(item: NotificationFieldOptions): NotificationFieldOptionsEditorModel { + if (item) { + this.mandatory = item.mandatory; + if(item.options) { item.options.map(x => this.options.push(new NotificationFieldInfoEditorModel().fromModel(x))); } + this.formatting = item.formatting; + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = NotificationFieldOptionsEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + mandatory: [{ value: this.mandatory, disabled: disabled }, context.getValidation('mandatory').validators], + formatting: [{ value: this.formatting, disabled: disabled }, context.getValidation('formatting').validators], + options: this.formBuilder.array( + (this.options ?? []).map( + (item, index) => new NotificationFieldInfoEditorModel( + this.validationErrorModel + ).fromModel(item).buildForm({ + rootPath: `options[${index}].` + }), context.getValidation('options') + ) + ), + }); + + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'mandatory', validators: [BackendErrorValidator(validationErrorModel,`${rootPath}mandatory`)] }); + baseValidationArray.push({ key: 'options', validators: [BackendErrorValidator(validationErrorModel,`${rootPath}options`)] }); + baseValidationArray.push({ key: 'formatting', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}formatting`)] }); + baseContext.validation = baseValidationArray; + return baseContext; + } + +} + +export class NotificationFieldInfoEditorModel implements NotificationFieldInfoPersist { + key: string; + dataType: NotificationDataType; + value: string; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor(public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + public fromModel(item: NotificationFieldInfo): NotificationFieldInfoEditorModel { + if (item) { + this.key = item.key; + this.dataType = item.dataType; + this.value = item.value; + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = NotificationFieldInfoEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + return this.formBuilder.group({ + key: [{ value: this.key, disabled: disabled }, context.getValidation('key').validators], + dataType: [{ value: this.dataType, disabled: disabled }, context.getValidation('dataType').validators], + value: [{ value: this.value, disabled: disabled }, context.getValidation('value').validators], + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + + baseValidationArray.push({ key: 'key', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}key`)] }); + baseValidationArray.push({ key: 'dataType', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}dataType`)] }); + baseValidationArray.push({ key: 'value', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}value`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } +} diff --git a/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.resolver.ts b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.resolver.ts new file mode 100644 index 000000000..9d5be154c --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.resolver.ts @@ -0,0 +1,44 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; +import { NotificationTemplate } from '@app/core/model/notification-template/notification-template'; +import { NotificationTemplateService } from '@app/core/services/notification-template/notification-template.service'; +import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; +import { BaseEditorResolver } from '@common/base/base-editor.resolver'; +import { Guid } from '@common/types/guid'; +import { takeUntil, tap } from 'rxjs/operators'; +import { nameof } from 'ts-simple-nameof'; + +@Injectable() +export class NotificationTemplateEditorResolver extends BaseEditorResolver { + + constructor(private notificationTemplateService: NotificationTemplateService, private breadcrumbService: BreadcrumbService) { + super(); + } + + public static lookupFields(): string[] { + return [ + ...BaseEditorResolver.lookupFields(), + nameof(x => x.id), + nameof(x => x.channel), + nameof(x => x.notificationType), + nameof(x => x.kind), + nameof(x => x.language), + nameof(x => x.createdAt), + nameof(x => x.updatedAt), + nameof(x => x.hash), + nameof(x => x.isActive) + ] + } + + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { + + const fields = [ + ...NotificationTemplateEditorResolver.lookupFields() + ]; + const id = route.paramMap.get('id'); + + if (id != null) { + return this.notificationTemplateService.getSingle(Guid.parse(id), fields).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.language.code)), takeUntil(this._destroyed)); + } + } +} diff --git a/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.service.ts b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.service.ts new file mode 100644 index 000000000..f8d5eace3 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/editor/notification-template-editor.service.ts @@ -0,0 +1,15 @@ +import { Injectable } from "@angular/core"; +import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; + +@Injectable() +export class NotificationTemplateEditorService { + private validationErrorModel: ValidationErrorModel; + + public setValidationErrorModel(validationErrorModel: ValidationErrorModel): void { + this.validationErrorModel = validationErrorModel; + } + + public getValidationErrorModel(): ValidationErrorModel { + return this.validationErrorModel; + } +} diff --git a/dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.html b/dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.html new file mode 100644 index 000000000..b899a28f3 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.html @@ -0,0 +1,36 @@ +
+ + + + + +
+
+
+

{{'NOTIFICATION-TEMPLATE-LISTING.FILTER.TITLE' | translate}}

+ +
+ + + {{'NOTIFICATION-TEMPLATE-LISTING.FILTER.IS-ACTIVE' | translate}} + + +
+ + +
+
+
+
+ + +
diff --git a/dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.scss b/dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.scss new file mode 100644 index 000000000..999f5a7c6 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.scss @@ -0,0 +1,25 @@ +.description-template-type-listing-filters { + +} + +::ng-deep.mat-mdc-menu-panel { + max-width: 100% !important; + height: 100% !important; +} + +:host::ng-deep.mat-mdc-menu-content:not(:empty) { + padding-top: 0 !important; +} + + +.filter-button{ + padding-top: .6rem; + padding-bottom: .6rem; + // .mat-icon{ + // font-size: 1.5em; + // width: 1.2em; + // height: 1.2em; + // } +} + + diff --git a/dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.ts b/dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.ts new file mode 100644 index 000000000..a6346be2c --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/listing/filters/notification-template-listing-filters.component.ts @@ -0,0 +1,91 @@ +import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { NotificationTemplateFilter } from '@app/core/query/notification-template.lookup'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; +import { BaseComponent } from '@common/base/base.component'; +import { nameof } from 'ts-simple-nameof'; + +@Component({ + selector: 'app-notification-template-listing-filters', + templateUrl: './notification-template-listing-filters.component.html', + styleUrls: ['./notification-template-listing-filters.component.scss'] +}) +export class NotificationTemplateListingFiltersComponent extends BaseComponent implements OnInit, OnChanges { + + @Input() readonly filter: NotificationTemplateFilter; + @Output() filterChange = new EventEmitter(); + + // * State + internalFilters: TenantListingFilters = this._getEmptyFilters(); + + protected appliedFilterCount: number = 0; + constructor( + public enumUtils: EnumUtils, + ) { super(); } + + ngOnInit() { + } + + ngOnChanges(changes: SimpleChanges): void { + const filterChange = changes[nameof(x => x.filter)]?.currentValue as NotificationTemplateFilter; + if (filterChange) { + this.updateFilters() + } + } + + + onSearchTermChange(searchTerm: string): void { + this.applyFilters() + } + + + protected updateFilters(): void { + this.internalFilters = this._parseToInternalFilters(this.filter); + this.appliedFilterCount = this._computeAppliedFilters(this.internalFilters); + } + + protected applyFilters(): void { + const { isActive } = this.internalFilters ?? {} + this.filterChange.emit({ + ...this.filter, + // like, + isActive: isActive ? [IsActive.Active] : [IsActive.Inactive] + }) + } + + + private _parseToInternalFilters(inputFilter: NotificationTemplateFilter): TenantListingFilters { + if (!inputFilter) { + return this._getEmptyFilters(); + } + + let { excludedIds, ids, isActive } = inputFilter; + + return { + isActive: (isActive ?? [])?.includes(IsActive.Active) || !isActive?.length, + } + + } + + private _getEmptyFilters(): TenantListingFilters { + return { + isActive: true + } + } + + private _computeAppliedFilters(filters: TenantListingFilters): number { + let count = 0; + if (filters?.isActive) { + count++ + } + return count; + } + + clearFilters() { + this.internalFilters = this._getEmptyFilters(); + } +} + +interface TenantListingFilters { + isActive: boolean; +} diff --git a/dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.html b/dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.html new file mode 100644 index 000000000..e38459e2f --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.html @@ -0,0 +1,95 @@ +
+
+ +
+
+

{{'NOTIFICATION-TEMPLATE-LISTING.TITLE' | translate}}

+ + +
+
+ +
+
+ + + + + + + + +
+
+ + + + +
+
+ + {{item?.name | nullifyValue}} +
+
+ + +
+
+ {{enumUtils.toDescriptionTemplateTypeStatusString(item.status) | nullifyValue}} +
+
+
+ + + + {{'NOTIFICATION-TEMPLATE-LISTING.FIELDS.CREATED-AT' | translate}}: + + {{item?.createdAt | dateTimeFormatter : 'short' | nullifyValue}} + + +
+
+ + + {{'NOTIFICATION-TEMPLATE-LISTING.FIELDS.UPDATED-AT' | translate}}: + + {{item?.updatedAt | dateTimeFormatter : 'short' | nullifyValue}} + + + +
+
+
+ + +
+
+ + + + + +
+
+
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.scss b/dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.scss new file mode 100644 index 000000000..6e1b48814 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.scss @@ -0,0 +1,60 @@ +.description-template-type-listing { + margin-top: 1.3rem; + margin-left: 1rem; + margin-right: 2rem; + + .mat-header-row{ + background: #f3f5f8; + } + .mat-card { + margin: 16px 0; + padding: 0px; + } + + .mat-row { + cursor: pointer; + min-height: 4.5em; + } + + mat-row:hover { + background-color: #eef5f6; + } + .mat-fab-bottom-right { + float: right; + z-index: 5; + } +} +.create-btn { + border-radius: 30px; + background-color: var(--secondary-color); + padding-left: 2em; + padding-right: 2em; + // color: #000; + + .button-text{ + display: inline-block; + } +} + +.dlt-btn { + color: rgba(0, 0, 0, 0.54); +} + +.status-chip{ + + border-radius: 20px; + padding-left: 1em; + padding-right: 1em; + padding-top: 0.2em; + font-size: .8em; +} + +.status-chip-finalized{ + color: #568b5a; + background: #9dd1a1 0% 0% no-repeat padding-box; +} + +.status-chip-draft{ + color: #00c4ff; + background: #d3f5ff 0% 0% no-repeat padding-box; +} diff --git a/dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.ts b/dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.ts new file mode 100644 index 000000000..c15d94102 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/listing/notification-template-listing.component.ts @@ -0,0 +1,175 @@ +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; +import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; +import { BaseListingComponent } from '@common/base/base-listing-component'; +import { PipeService } from '@common/formatting/pipe.service'; +import { DataTableDateTimeFormatPipe } from '@common/formatting/pipes/date-time-format.pipe'; +import { QueryResult } from '@common/model/query-result'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; +import { ColumnDefinition, ColumnsChangedEvent, HybridListingComponent, PageLoadEvent } from '@common/modules/hybrid-listing/hybrid-listing.component'; +import { Guid } from '@common/types/guid'; +import { TranslateService } from '@ngx-translate/core'; +import { Observable } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { nameof } from 'ts-simple-nameof'; +import { IsActiveTypePipe } from '@common/formatting/pipes/is-active-type.pipe'; +import { NotificationTemplate } from '@app/core/model/notification-template/notification-template'; +import { NotificationTemplateLookup } from '@app/core/query/notification-template.lookup'; +import { NotificationTemplateService } from '@app/core/services/notification-template/notification-template.service'; + +@Component({ + templateUrl: './NOTIFICATION-TEMPLATE-LISTING.component.html', + styleUrls: ['./NOTIFICATION-TEMPLATE-LISTING.component.scss'] +}) +export class NotificationTemplateListingComponent extends BaseListingComponent implements OnInit { + publish = false; + userSettingsKey = { key: 'NotificationTemplateListingUserSettings' }; + propertiesAvailableForOrder: ColumnDefinition[]; + + @ViewChild('actions', { static: true }) actions?: TemplateRef; + @ViewChild(HybridListingComponent, { static: true }) hybridListingComponent: HybridListingComponent; + + private readonly lookupFields: string[] = [ + nameof(x => x.id), + nameof(x => x.language.code), + nameof(x => x.channel), + nameof(x => x.updatedAt), + nameof(x => x.createdAt), + nameof(x => x.hash), + nameof(x => x.isActive) + ]; + + rowIdentity = x => x.id; + + constructor( + protected router: Router, + protected route: ActivatedRoute, + protected uiNotificationService: UiNotificationService, + protected httpErrorHandlingService: HttpErrorHandlingService, + protected queryParamsService: QueryParamsService, + private notificationTemplateService: NotificationTemplateService, + public authService: AuthService, + private pipeService: PipeService, + public enumUtils: EnumUtils, + private language: TranslateService, + private dialog: MatDialog + ) { + super(router, route, uiNotificationService, httpErrorHandlingService, queryParamsService); + // Lookup setup + // Default lookup values are defined in the user settings class. + this.lookup = this.initializeLookup(); + } + + ngOnInit() { + super.ngOnInit(); + } + + protected initializeLookup(): NotificationTemplateLookup { + const lookup = new NotificationTemplateLookup(); + lookup.metadata = { countAll: true }; + lookup.page = { offset: 0, size: this.ITEMS_PER_PAGE }; + lookup.isActive = [IsActive.Active]; + lookup.order = { items: [this.toDescSortField(nameof(x => x.createdAt))] }; + this.updateOrderUiFields(lookup.order); + + lookup.project = { + fields: this.lookupFields + }; + + return lookup; + } + + protected setupColumns() { + this.gridColumns.push(...[{ + prop: nameof(x => x.language.code), + sortable: true, + languageName: 'NOTIFICATION-TEMPLATE-LISTING.FIELDS.LANGUAGE' + }, { + prop: nameof(x => x.channel), + sortable: true, + languageName: 'NOTIFICATION-TEMPLATE-LISTING.FIELDS.CHANNEL', + }, + { + prop: nameof(x => x.createdAt), + sortable: true, + languageName: 'NOTIFICATION-TEMPLATE-LISTING.FIELDS.CREATED-AT', + pipe: this.pipeService.getPipe(DataTableDateTimeFormatPipe).withFormat('short') + }, + { + prop: nameof(x => x.updatedAt), + sortable: true, + languageName: 'NOTIFICATION-TEMPLATE-LISTING.FIELDS.UPDATED-AT', + pipe: this.pipeService.getPipe(DataTableDateTimeFormatPipe).withFormat('short') + }, + { + prop: nameof(x => x.isActive), + sortable: true, + languageName: 'NOTIFICATION-TEMPLATE-LISTING.FIELDS.IS-ACTIVE', + pipe: this.pipeService.getPipe(IsActiveTypePipe) + }, + { + alwaysShown: true, + cellTemplate: this.actions, + maxWidth: 120 + } + ]); + this.propertiesAvailableForOrder = this.gridColumns.filter(x => x.sortable); + } + + // + // Listing Component functions + // + onColumnsChanged(event: ColumnsChangedEvent) { + super.onColumnsChanged(event); + this.onColumnsChangedInternal(event.properties.map(x => x.toString())); + } + + private onColumnsChangedInternal(columns: string[]) { + // Here are defined the projection fields that always requested from the api. + const fields = new Set(this.lookupFields); + this.gridColumns.map(x => x.prop) + .filter(x => !columns?.includes(x as string)) + .forEach(item => { + fields.delete(item as string) + }); + this.lookup.project = { fields: [...fields] }; + this.onPageLoad({ offset: 0 } as PageLoadEvent); + } + + protected loadListing(): Observable> { + return this.notificationTemplateService.query(this.lookup); + } + + public deleteType(id: Guid) { + if (id) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + data: { + isDeleteConfirmation: true, + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL') + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.notificationTemplateService.delete(id).pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(), + error => this.onCallbackError(error) + ); + } + }); + } + } + + onCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); + this.ngOnInit(); + } +} diff --git a/dmp-frontend/src/app/ui/admin/notification-template/notification-template.module.ts b/dmp-frontend/src/app/ui/admin/notification-template/notification-template.module.ts new file mode 100644 index 000000000..fa01671c2 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/notification-template.module.ts @@ -0,0 +1,43 @@ +import { DragDropModule } from '@angular/cdk/drag-drop'; +import { NgModule } from "@angular/core"; +import { AutoCompleteModule } from "@app/library/auto-complete/auto-complete.module"; +import { UrlListingModule } from '@app/library/url-listing/url-listing.module'; +import { CommonFormattingModule } from '@common/formatting/common-formatting.module'; +import { CommonFormsModule } from '@common/forms/common-forms.module'; +import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module'; +import { HybridListingModule } from "@common/modules/hybrid-listing/hybrid-listing.module"; +import { TextFilterModule } from "@common/modules/text-filter/text-filter.module"; +import { UserSettingsModule } from "@common/modules/user-settings/user-settings.module"; +import { CommonUiModule } from '@common/ui/common-ui.module'; +import { NgxDropzoneModule } from "ngx-dropzone"; +import { NotificationTemplateListingComponent } from './listing/notification-template-listing.component'; +import { RichTextEditorModule } from '@app/library/rich-text-editor/rich-text-editor.module'; +import { NotificationTemplateRoutingModule } from './notification-template.routing'; +import { NotificationTemplateEditorComponent } from './editor/notification-template-editor.component'; +import { NotificationTemplateListingFiltersComponent } from './listing/filters/notification-template-listing-filters.component'; +import { MatIconModule } from '@angular/material/icon'; + +@NgModule({ + imports: [ + CommonUiModule, + CommonFormsModule, + UrlListingModule, + ConfirmationDialogModule, + NotificationTemplateRoutingModule, + NgxDropzoneModule, + DragDropModule, + AutoCompleteModule, + HybridListingModule, + TextFilterModule, + UserSettingsModule, + CommonFormattingModule, + RichTextEditorModule, + MatIconModule + ], + declarations: [ + NotificationTemplateEditorComponent, + NotificationTemplateListingComponent, + NotificationTemplateListingFiltersComponent + ] +}) +export class NotificationTemplateModule { } diff --git a/dmp-frontend/src/app/ui/admin/notification-template/notification-template.routing.ts b/dmp-frontend/src/app/ui/admin/notification-template/notification-template.routing.ts new file mode 100644 index 000000000..5a0e1bfd6 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/notification-template/notification-template.routing.ts @@ -0,0 +1,58 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { AdminAuthGuard } from '@app/core/admin-auth-guard.service'; +import { AppPermission } from '@app/core/common/enum/permission.enum'; +import { AuthGuard } from '@app/core/auth-guard.service'; +import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; +import { PendingChangesGuard } from '@common/forms/pending-form-changes/pending-form-changes-guard.service'; +import { NotificationTemplateListingComponent } from './listing/notification-template-listing.component'; +import { NotificationTemplateEditorComponent } from './editor/notification-template-editor.component'; +import { NotificationTemplateEditorResolver } from './editor/notification-template-editor.resolver'; + +const routes: Routes = [ + { + path: '', + component: NotificationTemplateListingComponent, + canActivate: [AuthGuard] + }, + { + path: 'new', + canActivate: [AuthGuard], + component: NotificationTemplateEditorComponent, + canDeactivate: [PendingChangesGuard], + data: { + authContext: { + permissions: [AppPermission.EditNotificationTemplate] + }, + ...BreadcrumbService.generateRouteDataConfiguration({ + title: 'BREADCRUMBS.NEW-TENANT' + }) + } + }, + { + path: ':id', + canActivate: [AuthGuard], + component: NotificationTemplateEditorComponent, + canDeactivate: [PendingChangesGuard], + resolve: { + 'entity': NotificationTemplateEditorResolver + }, + data: { + ...BreadcrumbService.generateRouteDataConfiguration({ + title: 'BREADCRUMBS.EDIT-TENANT' + }), + authContext: { + permissions: [AppPermission.EditNotificationTemplate] + } + } + + }, + { path: '**', loadChildren: () => import('@common/modules/page-not-found/page-not-found.module').then(m => m.PageNotFoundModule) }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], + providers: [NotificationTemplateEditorResolver] +}) +export class NotificationTemplateRoutingModule { } diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts index 011c90d49..415f3afdb 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts @@ -58,7 +58,8 @@ export const ADMIN_ROUTES: RouteInfo[] = [ { path: '/tenants', title: 'SIDE-BAR.TENANTS', icon: 'tenancy' }, { path: '/users', title: 'SIDE-BAR.USERS', icon: 'people' }, { path: '/languages', title: 'SIDE-BAR.LANGUAGES', icon: 'language' }, - { path: '/supportive-material', title: 'SIDE-BAR.SUPPORTIVE-MATERIAL', icon: 'import_contacts' }, + { path: '/supportive-material', title: 'SIDE-BAR.SUPPORTIVE-MATERIAL', icon: 'dataset_linked' }, + { path: '/notification-templates', title: 'SIDE-BAR.NOTIFICATION-TEMPLATES', icon: 'build'}, { path: '/index-managment', title: 'SIDE-BAR.MAINTENANCE', icon: 'build'} ]; diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 588ceebb5..f27e8e9d4 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -253,7 +253,8 @@ "EDIT-REFERENCE": "Edit", "LANGUAGES": "Languages", "NEW-LANGUAGE": "New", - "EDIT-LANGUAGE": "Edit" + "EDIT-LANGUAGE": "Edit", + "NOTIFICATION-TEMPLATES": "Notification Templates" }, "COOKIE": { "MESSAGE": "This website uses cookies to enhance the user experience.", @@ -352,7 +353,8 @@ "TENANTS": "Tenants", "REFERENCES": "References", "LANGUAGES": "Languages", - "MAINTENANCE": "Maintenance" + "MAINTENANCE": "Maintenance", + "NOTIFICATION-TEMPLATES":"Notification Templates" }, "DESCRIPTION-TEMPLATE-EDITOR": { "TITLE": { @@ -1213,6 +1215,36 @@ "SUCCESSFUL-DELETE": "Successful Delete", "UNSUCCESSFUL-DELETE": "This item could not be deleted." }, + "NOTIFICATION-TEMPLATE-LISTING": { + "TITLE": "Notification Templates", + "CREATE": "Create Notification Template", + "FIELDS": { + "NAME": "Name", + "LANGUAGE":"Language", + "CHANNEL":"Channel", + "UPDATED-AT": "Updated", + "CREATED-AT": "Created", + "IS-ACTIVE":"Is Active" + }, + "FILTER": { + "TITLE": "Filters", + "IS-ACTIVE": "Is Active", + "STATUS": "Status", + "CANCEL": "Cancel", + "APPLY-FILTERS": "Apply filters" + }, + "CONFIRM-DELETE-DIALOG": { + "MESSAGE": "Would you like to delete this Notification Template?", + "CONFIRM-BUTTON": "Yes, delete", + "CANCEL-BUTTON": "No" + }, + "ACTIONS": { + "DELETE": "Delete", + "EDIT": "Edit" + }, + "SUCCESSFUL-DELETE": "Successful Delete", + "UNSUCCESSFUL-DELETE": "This item could not be deleted." + }, "SUPPORTIVE-MATERIAL-EDITOR": { "TITLE": "Supportive Material", "FIELDS": { @@ -1260,6 +1292,44 @@ "UNSUCCESSFUL": "Something went wrong" } }, + "NOTIFICATION-SERVICE": { + "NOTIFICATION-TEMPLATE-EDITOR":{ + "NEW": "New Notification Template", + "FIELDS": { + "LANGUAGE": "Language", + "CHANNEL": "Channel", + "KIND": "Kind", + "OPTIONAL-TITLE": "Optional Fields", + "FIELD": "Field", + "KEY":"Key", + "DATA-TYPE":"Data Type", + "VALUE":"Value", + "SUBJECT-SECTION": "Subject Section", + "SUBJECT-TEXT": "Subject Text", + "SUBJECT-KEY": "Subject Key", + "SUBJECT-FIELD-OPTIONS": "Subject Field Options", + "BODY-SECTION": "Body Section", + "BODY-TEXT": "Body Text", + "BODY-KEY": "Body Key", + "BODY-FIELD-OPTIONS": "Body Field Options", + "MANDATORY": "Mandatory", + "MANDATORY-PLACEHOLDER": "New field..", + "EXTRA-OPTIONS": "Extra Options", + "PRIORITY-KEY": "Priority Key", + "ALLOW-ATTACHMENTS": "Allow Attachments", + "CC": "CC", + "CC-MODE": "CC Mode", + "BCC": "BCC", + "BCC-MODE": "BCC Mode", + "EXTRA-DATA-KEYS": "EXTRA-DATA-KEYS" + }, + "ACTIONS": { + "SAVE": "Save", + "CANCEL": "Cancel", + "DELETE": "Delete" + } + } + }, "DESCRIPTION-TEMPLATE-TYPE-EDITOR": { "NEW": "New Description Type", "FIELDS": { @@ -2065,6 +2135,28 @@ "REFERENCE-SOURCE-TYPE":{ "INTERNAL": "Internal", "EXTERNAL": "External" + }, + "NOTIFICATION-TEMPLATE-KIND":{ + "DRAFT": "Draft", + "SECONDARY": "Secondary", + "PRIMARY": "Primary", + "DEFAULT": "Default" + }, + "NOTIFICATION-TEMPLATE-CHANNEL":{ + "EMAIL": "Email", + "INAPP": "In App" + }, + "NOTIFICATION-TEMPLATE-DATA-TYPE":{ + "INTEGER": "Integer", + "DEMICAL": "Demical", + "DOUBLE": "Double", + "DATE-TIME": "Date Time", + "STRING": "String" + }, + "NOTIFICATION-TEMPLATE-EMAIL-OVERRIDE-MODE":{ + "NOT": "Not Override", + "ADDITIVE": "Additive", + "REPLACE": "Replace" } }, "ADDRESEARCHERS-EDITOR": {