package eu.eudat.model.persist.descriptionproperties; import eu.eudat.commons.enums.DescriptionStatus; import eu.eudat.commons.enums.FieldValidationType; import eu.eudat.commons.types.descriptiontemplate.DefinitionEntity; import eu.eudat.commons.types.descriptiontemplate.FieldEntity; import eu.eudat.commons.types.descriptiontemplate.FieldSetEntity; import eu.eudat.commons.validation.BaseValidator; import eu.eudat.convention.ConventionService; import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.model.persist.validation.StatusAware; import gr.cite.tools.validation.ValidatorFactory; import gr.cite.tools.validation.specification.Specification; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Scope; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Component; import java.util.*; import java.util.stream.Collectors; public class PropertyDefinitionPersist { public final static String _fieldSets = "fieldSets"; private Map fieldSets; public Map getFieldSets() { return fieldSets; } public void setFieldSets(Map fieldSets) { this.fieldSets = fieldSets; } @Component(PropertyDefinitionPersistValidator.ValidatorName) @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public static class PropertyDefinitionPersistValidator extends BaseValidator implements StatusAware { public static final String ValidatorName = "Description.PropertyDefinitionPersistValidator"; private final MessageSource messageSource; private final ValidatorFactory validatorFactory; private DescriptionStatus status; private DefinitionEntity definition; protected PropertyDefinitionPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { super(conventionService, errors); this.messageSource = messageSource; this.validatorFactory = validatorFactory; } @Override protected Class modelClass() { return PropertyDefinitionPersist.class; } @Override protected List specifications(PropertyDefinitionPersist item) { return Arrays.asList( this.spec() .iff(() -> this.status == DescriptionStatus.Finalized) .must(() -> !this.isNull(item.getFieldSets()) && !item.getFieldSets().isEmpty()) .failOn(PropertyDefinitionPersist._fieldSets).failWith(messageSource.getMessage("Validation_Required", new Object[]{PropertyDefinitionPersist._fieldSets}, LocaleContextHolder.getLocale())), this.spec() .must(() -> this.isListNullOrEmpty(this.getMissingFieldSetEntity(item))) .failOn(PropertyDefinitionPersist._fieldSets).failWith(messageSource.getMessage("Validation.MissingFields", new Object[]{this.serializeMissingFieldSets(this.getMissingFieldSetEntity(item))}, LocaleContextHolder.getLocale())), this.spec() .must(() -> this.isListNullOrEmpty(this.getMissingFieldsEntity(item))) .failOn(PropertyDefinitionPersist._fieldSets).failWith(messageSource.getMessage("Validation.MissingFields", new Object[]{this.serializeMissingFields(this.getMissingFieldsEntity(item))}, LocaleContextHolder.getLocale())), this.mapSpec() .iff(() -> !this.isNull(item.getFieldSets())) .on(PropertyDefinitionPersist._fieldSets) .over(item.getFieldSets()) .mapKey((k) -> ((String)k)) .using((itm) -> { FieldSetEntity fieldSetEntity = definition != null ? definition.getFieldSetById((String)itm.getKey()).stream().findFirst().orElse(null) : null; return this.validatorFactory.validator(PropertyDefinitionFieldSetPersist.PersistValidator.class).withFieldSetEntity(fieldSetEntity).setStatus(this.status); }) ); } @Override public PropertyDefinitionPersistValidator setStatus(DescriptionStatus status) { this.status = status; return this; } public PropertyDefinitionPersistValidator withDefinition(DefinitionEntity definition) { this.definition = definition; return this; } private List getMissingFieldSetEntity(PropertyDefinitionPersist item){ List missingMultipleFieldSets = new ArrayList<>(); if (definition == null || definition.getAllFieldSets() == null) return missingMultipleFieldSets; for (FieldSetEntity fieldSet: definition.getAllFieldSets()) { boolean requiredAtLeastOneFieldSet = fieldSet.getMultiplicity() != null && fieldSet.getMultiplicity().getMin() > 0; if (requiredAtLeastOneFieldSet) { if (item == null || item.getFieldSets() == null) missingMultipleFieldSets.add(fieldSet); if (item.getFieldSets() != null) { PropertyDefinitionFieldSetPersist fieldSetPersist = item.getFieldSets().getOrDefault(fieldSet.getId(), null); if (fieldSetPersist == null) missingMultipleFieldSets.add(fieldSet); } } } return missingMultipleFieldSets; } private List getMissingFieldsEntity(PropertyDefinitionPersist item){ List missingFields = new ArrayList<>(); if (definition == null || definition.getAllFieldSets() == null) return missingFields; for (FieldSetEntity fieldSet: definition.getAllFieldSets()) { if (fieldSet.getFields() == null) continue; for(FieldEntity field : fieldSet.getFields()){ if (field.getValidations() == null) continue; if (field.getValidations().contains(FieldValidationType.Required)){ if (item == null || item.getFieldSets() == null) { missingFields.add(field); continue; } PropertyDefinitionFieldSetPersist propertyDefinitionFieldSetPersist = item.getFieldSets().getOrDefault(fieldSet.getId(), null); if (propertyDefinitionFieldSetPersist == null || propertyDefinitionFieldSetPersist.getItems() == null) { missingFields.add(field); continue; } for (PropertyDefinitionFieldSetItemPersist propertyDefinitionFieldSetItemPersist: propertyDefinitionFieldSetPersist.getItems()) { if (propertyDefinitionFieldSetItemPersist.getFields() == null){ missingFields.add(field); continue; } FieldPersist fieldPersist = propertyDefinitionFieldSetItemPersist.getFields().getOrDefault(field.getId(), null); if (fieldPersist == null){ missingFields.add(field); } } } } } return missingFields; } private String serializeMissingFieldSets (List missingFieldSets){ if (missingFieldSets == null) return ""; return missingFieldSets.stream().map(x -> x.getId()).collect(Collectors.joining(", ")); } private String serializeMissingFields (List missingFields){ if (missingFields == null) return ""; return missingFields.stream().map(x -> x.getId()).collect(Collectors.joining(", ")); } } }