From dd9461bc7a422f2aad4bcf1886bb4eeb28a381ec Mon Sep 17 00:00:00 2001 From: sgiannopoulos Date: Thu, 2 May 2024 15:57:19 +0300 Subject: [PATCH] default value implementation --- .../opencdmp/commons/JsonHandlingService.java | 14 +-- .../DefaultValueEntity.java | 61 ++++++++++ .../descriptiontemplate/FieldEntity.java | 30 ++--- .../descriptiontemplate/FieldSetEntity.java | 22 ++-- .../types/descriptiontemplate/RuleEntity.java | 3 + ...ptionTemplateDefaultValueImportExport.java | 57 ++++++++++ .../DescriptionTemplateFieldImportExport.java | 24 ++-- .../DescriptionTemplateRuleImportExport.java | 3 + .../commons/xmladapter/InstantXmlAdapter.java | 21 ++++ .../FieldCommonModelBuilder.java | 10 +- .../DefaultValueBuilder.java | 66 +++++++++++ .../FieldBuilder.java | 20 ++-- .../DefaultValueCensor.java | 39 +++++++ .../FieldCensor.java | 17 +-- .../DefaultValue.java | 53 +++++++++ .../descriptiontemplatedefinition/Field.java | 25 ++--- .../DescriptionFieldToDatasetFieldMapper.java | 2 +- .../DefaultValuePersist.java | 85 ++++++++++++++ .../FieldPersist.java | 50 +++++---- .../model/publicapi/datasetwizard/Field.java | 34 +++--- .../DescriptionTemplateServiceImpl.java | 62 ++++++++++- .../FieldSetExpanderService.java | 7 ++ .../FieldSetExpanderServiceConfiguration.java | 18 +++ .../FieldSetExpanderServiceImpl.java | 36 ++++++ .../FieldSetExpanderServiceProperties.java | 47 ++++++++ .../controllers/DescriptionController.java | 19 +++- ...ublicDatasetsDescriptionDocumentation.java | 5 +- .../src/main/resources/config/application.yml | 1 + .../resources/config/field-set-expander.yml | 53 +++++++++ .../description-template-persist.ts | 9 +- .../description-template.ts | 10 +- ...mplate-editor-default-value.component.html | 10 +- ...ption-template-editor-field.component.html | 19 +++- ...ription-template-editor-field.component.ts | 56 +++++++++- ...mplate-editor-visibility-rule.component.ts | 4 +- .../description-template-editor.model.ts | 104 +++++++++++++++++- .../description-template-editor.resolver.ts | 7 +- .../editor/description-editor.model.ts | 8 +- .../editor/description-editor.resolver.ts | 48 +------- .../form-field/form-field.component.html | 1 + ...escriptionTemplateXmlMigrationService.java | 50 ++++++++- 41 files changed, 1008 insertions(+), 202 deletions(-) create mode 100644 backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/DefaultValueEntity.java create mode 100644 backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateDefaultValueImportExport.java create mode 100644 backend/core/src/main/java/org/opencdmp/commons/xmladapter/InstantXmlAdapter.java create mode 100644 backend/core/src/main/java/org/opencdmp/model/builder/descriptiontemplatedefinition/DefaultValueBuilder.java create mode 100644 backend/core/src/main/java/org/opencdmp/model/censorship/descriptiontemplatedefinition/DefaultValueCensor.java create mode 100644 backend/core/src/main/java/org/opencdmp/model/descriptiontemplatedefinition/DefaultValue.java create mode 100644 backend/core/src/main/java/org/opencdmp/model/persist/descriptiontemplatedefinition/DefaultValuePersist.java create mode 100644 backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderService.java create mode 100644 backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceConfiguration.java create mode 100644 backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceImpl.java create mode 100644 backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceProperties.java create mode 100644 backend/web/src/main/resources/config/field-set-expander.yml diff --git a/backend/core/src/main/java/org/opencdmp/commons/JsonHandlingService.java b/backend/core/src/main/java/org/opencdmp/commons/JsonHandlingService.java index 38c92f799..24592328b 100644 --- a/backend/core/src/main/java/org/opencdmp/commons/JsonHandlingService.java +++ b/backend/core/src/main/java/org/opencdmp/commons/JsonHandlingService.java @@ -12,24 +12,24 @@ import java.util.HashMap; import java.util.Map; @Component -@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) +@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) public class JsonHandlingService { private final ObjectMapper objectMapper; public JsonHandlingService() { this.objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JavaTimeModule()); + this.objectMapper.registerModule(new JavaTimeModule()); } public String toJson(Object item) throws JsonProcessingException { if (item == null) return null; - return objectMapper.writeValueAsString(item); + return this.objectMapper.writeValueAsString(item); } public String toJsonSafe(Object item) { if (item == null) return null; try { - return objectMapper.writeValueAsString(item); + return this.objectMapper.writeValueAsString(item); } catch (Exception ex) { return null; } @@ -37,18 +37,18 @@ public class JsonHandlingService { public T fromJson(Class type, String json) throws JsonProcessingException { if (json == null) return null; - return objectMapper.readValue(json, type); + return this.objectMapper.readValue(json, type); } public HashMap mapFromJson(String json) throws JsonProcessingException { - ObjectReader reader = objectMapper.readerFor(Map.class); + ObjectReader reader = this.objectMapper.readerFor(Map.class); return reader.readValue(json); } public T fromJsonSafe(Class type, String json) { if (json == null) return null; try { - return objectMapper.readValue(json, type); + return this.objectMapper.readValue(json, type); } catch (Exception ex) { return null; } diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/DefaultValueEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/DefaultValueEntity.java new file mode 100644 index 000000000..98a2dd922 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/DefaultValueEntity.java @@ -0,0 +1,61 @@ +package org.opencdmp.commons.types.descriptiontemplate; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import org.opencdmp.commons.xmladapter.InstantXmlAdapter; + +import java.time.Instant; +import java.util.List; + +@XmlAccessorType(XmlAccessType.FIELD) +public class DefaultValueEntity { + + @XmlElementWrapper(name = "textListValues") + @XmlElement(name = "textListValue") + private List textListValue; + @XmlElement(name="value") + private String textValue; + + @XmlElement(name = "dateValue") + @XmlJavaTypeAdapter(InstantXmlAdapter.class) + private Instant dateValue; + + @XmlElement(name = "booleanValue") + private Boolean booleanValue; + + public List getTextListValue() { + return this.textListValue; + } + + public void setTextListValue(List textListValue) { + this.textListValue = textListValue; + } + + public String getTextValue() { + return this.textValue; + } + + public void setTextValue(String textValue) { + this.textValue = textValue; + } + + public Instant getDateValue() { + return this.dateValue; + } + + public void setDateValue(Instant dateValue) { + this.dateValue = dateValue; + } + + public Boolean getBooleanValue() { + return this.booleanValue; + } + + public void setBooleanValue(Boolean booleanValue) { + this.booleanValue = booleanValue; + } +} + diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldEntity.java index 58b260e87..fd0ff3329 100644 --- a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldEntity.java +++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldEntity.java @@ -1,8 +1,8 @@ package org.opencdmp.commons.types.descriptiontemplate; +import jakarta.xml.bind.annotation.*; import org.opencdmp.commons.enums.FieldValidationType; import org.opencdmp.commons.types.descriptiontemplate.fielddata.*; -import jakarta.xml.bind.annotation.*; import java.util.List; @@ -17,8 +17,8 @@ public class FieldEntity { private List schematics; @XmlAttribute(name="numbering") private String numbering; - @XmlAttribute(name="defaultValue") - private String defaultValue; + @XmlElement(name="defaultValue") + private DefaultValueEntity defaultValue; @XmlElementWrapper(name = "visibilityRules") @XmlElement(name = "rule") private List visibilityRules; @@ -39,57 +39,57 @@ public class FieldEntity { private Boolean includeInExport; public String getId() { - return id; + return this.id; } public void setId(String id) { this.id = id; } public int getOrdinal() { - return ordinal; + return this.ordinal; } public void setOrdinal(int ordinal) { this.ordinal = ordinal; } public List getSchematics() { - return schematics; + return this.schematics; } public void setSchematics(List schematics) { this.schematics = schematics; } public BaseFieldDataEntity getData() { - return data; + return this.data; } public void setData(BaseFieldDataEntity data) { this.data = data; } - public String getDefaultValue() { - return defaultValue; + public DefaultValueEntity getDefaultValue() { + return this.defaultValue; } - public void setDefaultValue(String defaultValue) { + + public void setDefaultValue(DefaultValueEntity defaultValue) { this.defaultValue = defaultValue; } - public List getValidations() { - return validations; + return this.validations; } public void setValidations(List validations) { this.validations = validations; } public String getNumbering() { - return numbering; + return this.numbering; } public void setNumbering(String numbering) { this.numbering = numbering; } public Boolean getIncludeInExport() { - return includeInExport; + return this.includeInExport; } public void setIncludeInExport(Boolean includeInExport) { @@ -97,7 +97,7 @@ public class FieldEntity { } public List getVisibilityRules() { - return visibilityRules; + return this.visibilityRules; } public void setVisibilityRules(List visibilityRules) { diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldSetEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldSetEntity.java index 5ab80101d..71464f20c 100644 --- a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldSetEntity.java +++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/FieldSetEntity.java @@ -33,70 +33,70 @@ public class FieldSetEntity { private boolean hasCommentField; public List getFields() { - return fields; + return this.fields; } public void setFields(List fieldEntities) { this.fields = fieldEntities; } public String getId() { - return id; + return this.id; } public void setId(String id) { this.id = id; } public int getOrdinal() { - return ordinal; + return this.ordinal; } public void setOrdinal(int ordinal) { this.ordinal = ordinal; } public String getTitle() { - return title; + return this.title; } public void setTitle(String title) { this.title = title; } public String getDescription() { - return description; + return this.description; } public void setDescription(String description) { this.description = description; } public String getExtendedDescription() { - return extendedDescription; + return this.extendedDescription; } public void setExtendedDescription(String extendedDescription) { this.extendedDescription = extendedDescription; } public MultiplicityEntity getMultiplicity() { - return multiplicity; + return this.multiplicity; } public void setMultiplicity(MultiplicityEntity multiplicity) { this.multiplicity = multiplicity; } public boolean getHasCommentField() { - return hasCommentField; + return this.hasCommentField; } public void setHasCommentField(boolean hasCommentField) { this.hasCommentField = hasCommentField; } public String getNumbering() { - return numbering; + return this.numbering; } public void setNumbering(String numbering) { this.numbering = numbering; } public String getAdditionalInformation() { - return additionalInformation; + return this.additionalInformation; } public void setAdditionalInformation(String additionalInformation) { this.additionalInformation = additionalInformation; @@ -112,7 +112,7 @@ public class FieldSetEntity { } public boolean getHasMultiplicity() { - return hasMultiplicity; + return this.hasMultiplicity; } public void setHasMultiplicity(boolean hasMultiplicity) { diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/RuleEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/RuleEntity.java index e222b8e39..ad35b184a 100644 --- a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/RuleEntity.java +++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/RuleEntity.java @@ -1,6 +1,8 @@ package org.opencdmp.commons.types.descriptiontemplate; import jakarta.xml.bind.annotation.*; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import org.opencdmp.commons.xmladapter.InstantXmlAdapter; import java.time.Instant; import java.util.List; @@ -17,6 +19,7 @@ public class RuleEntity { private List textListValue; @XmlElement(name = "dateValue") + @XmlJavaTypeAdapter(InstantXmlAdapter.class) private Instant dateValue; @XmlElement(name = "booleanValue") diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateDefaultValueImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateDefaultValueImportExport.java new file mode 100644 index 000000000..b9b0d9388 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateDefaultValueImportExport.java @@ -0,0 +1,57 @@ +package org.opencdmp.commons.types.descriptiontemplate.importexport; + +import jakarta.xml.bind.annotation.*; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import org.opencdmp.commons.xmladapter.InstantXmlAdapter; + +import java.time.Instant; +import java.util.List; + +@XmlAccessorType(XmlAccessType.FIELD) +public class DescriptionTemplateDefaultValueImportExport { + + @XmlAttribute(name="value") + private String textValue; + + @XmlElementWrapper(name = "textListValues") + @XmlElement(name = "textListValue") + private List textListValue; + @XmlElement(name = "dateValue") + @XmlJavaTypeAdapter(InstantXmlAdapter.class) + private Instant dateValue; + + @XmlElement(name = "booleanValue") + private Boolean booleanValue; + + public String getTextValue() { + return this.textValue; + } + + public void setTextValue(String textValue) { + this.textValue = textValue; + } + + public List getTextListValue() { + return this.textListValue; + } + + public void setTextListValue(List textListValue) { + this.textListValue = textListValue; + } + + public Instant getDateValue() { + return this.dateValue; + } + + public void setDateValue(Instant dateValue) { + this.dateValue = dateValue; + } + + public Boolean getBooleanValue() { + return this.booleanValue; + } + + public void setBooleanValue(Boolean booleanValue) { + this.booleanValue = booleanValue; + } +} \ No newline at end of file diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateFieldImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateFieldImportExport.java index 47366c931..27fccd260 100644 --- a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateFieldImportExport.java +++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateFieldImportExport.java @@ -1,9 +1,9 @@ package org.opencdmp.commons.types.descriptiontemplate.importexport; +import jakarta.xml.bind.annotation.*; import org.opencdmp.commons.enums.FieldType; import org.opencdmp.commons.enums.FieldValidationType; import org.opencdmp.commons.types.descriptiontemplate.importexport.fielddata.*; -import jakarta.xml.bind.annotation.*; import java.util.List; @@ -24,7 +24,7 @@ public class DescriptionTemplateFieldImportExport { private List validations; @XmlElement(name = "defaultValue") - private String defaultValue; + private DescriptionTemplateDefaultValueImportExport defaultValue; @XmlElementWrapper(name = "visibilityRules") @XmlElement(name = "visibilityRule") @@ -48,7 +48,7 @@ public class DescriptionTemplateFieldImportExport { private List schematics; public String getId() { - return id; + return this.id; } public void setId(String id) { @@ -56,7 +56,7 @@ public class DescriptionTemplateFieldImportExport { } public int getOrdinal() { - return ordinal; + return this.ordinal; } public void setOrdinal(int ordinal) { @@ -64,23 +64,23 @@ public class DescriptionTemplateFieldImportExport { } public String getNumbering() { - return numbering; + return this.numbering; } public void setNumbering(String numbering) { this.numbering = numbering; } - public String getDefaultValue() { - return defaultValue; + public DescriptionTemplateDefaultValueImportExport getDefaultValue() { + return this.defaultValue; } - public void setDefaultValue(String defaultValue) { + public void setDefaultValue(DescriptionTemplateDefaultValueImportExport defaultValue) { this.defaultValue = defaultValue; } public FieldType getFieldType() { - return fieldType; + return this.fieldType; } public void setFieldType(FieldType fieldType) { @@ -96,7 +96,7 @@ public class DescriptionTemplateFieldImportExport { } public List getValidations() { - return validations; + return this.validations; } public void setValidations(List validations) { @@ -104,7 +104,7 @@ public class DescriptionTemplateFieldImportExport { } public List getSchematics() { - return schematics; + return this.schematics; } public void setSchematics(List schematics) { @@ -112,7 +112,7 @@ public class DescriptionTemplateFieldImportExport { } public List getVisibilityRules() { - return visibilityRules; + return this.visibilityRules; } public void setVisibilityRules(List visibilityRules) { diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateRuleImportExport.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateRuleImportExport.java index 811edb530..f5bac130a 100644 --- a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateRuleImportExport.java +++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/importexport/DescriptionTemplateRuleImportExport.java @@ -1,6 +1,8 @@ package org.opencdmp.commons.types.descriptiontemplate.importexport; import jakarta.xml.bind.annotation.*; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import org.opencdmp.commons.xmladapter.InstantXmlAdapter; import java.time.Instant; import java.util.List; @@ -17,6 +19,7 @@ public class DescriptionTemplateRuleImportExport { @XmlElement(name = "textListValue") private List textListValue; @XmlElement(name = "dateValue") + @XmlJavaTypeAdapter(InstantXmlAdapter.class) private Instant dateValue; @XmlElement(name = "booleanValue") diff --git a/backend/core/src/main/java/org/opencdmp/commons/xmladapter/InstantXmlAdapter.java b/backend/core/src/main/java/org/opencdmp/commons/xmladapter/InstantXmlAdapter.java new file mode 100644 index 000000000..da74a4b84 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/commons/xmladapter/InstantXmlAdapter.java @@ -0,0 +1,21 @@ +package org.opencdmp.commons.xmladapter; + +import jakarta.xml.bind.annotation.adapters.XmlAdapter; + +import java.time.Instant; +import java.time.format.DateTimeFormatter; + +public class InstantXmlAdapter extends XmlAdapter { + public InstantXmlAdapter() { + } + + @Override + public Instant unmarshal(String stringValue) { + return stringValue != null ? DateTimeFormatter.ISO_INSTANT.parse(stringValue, Instant::from) : null; + } + + @Override + public String marshal(Instant value) { + return value != null ? DateTimeFormatter.ISO_INSTANT.format(value) : null; + } +} diff --git a/backend/core/src/main/java/org/opencdmp/model/builder/commonmodels/descriptiontemplate/FieldCommonModelBuilder.java b/backend/core/src/main/java/org/opencdmp/model/builder/commonmodels/descriptiontemplate/FieldCommonModelBuilder.java index c6f26ac49..a4f72b159 100644 --- a/backend/core/src/main/java/org/opencdmp/model/builder/commonmodels/descriptiontemplate/FieldCommonModelBuilder.java +++ b/backend/core/src/main/java/org/opencdmp/model/builder/commonmodels/descriptiontemplate/FieldCommonModelBuilder.java @@ -1,5 +1,8 @@ package org.opencdmp.model.builder.commonmodels.descriptiontemplate; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.logging.LoggerService; import org.opencdmp.authorization.AuthorizationFlags; import org.opencdmp.commonmodels.models.descriptiotemplate.FieldModel; import org.opencdmp.commons.enums.FieldValidationType; @@ -9,9 +12,6 @@ import org.opencdmp.model.builder.commonmodels.BaseCommonModelBuilder; import org.opencdmp.model.builder.commonmodels.CommonModelBuilderItemResponse; import org.opencdmp.service.fielddatahelper.FieldDataHelperService; import org.opencdmp.service.fielddatahelper.FieldDataHelperServiceProvider; -import gr.cite.tools.data.builder.BuilderFactory; -import gr.cite.tools.exception.MyApplicationException; -import gr.cite.tools.logging.LoggerService; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -24,7 +24,7 @@ import java.util.List; import java.util.Optional; @Component("commonmodels.descriptiontemplate") -@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class FieldCommonModelBuilder extends BaseCommonModelBuilder { private final BuilderFactory builderFactory; private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); @@ -55,7 +55,7 @@ public class FieldCommonModelBuilder extends BaseCommonModelBuilder()); diff --git a/backend/core/src/main/java/org/opencdmp/model/builder/descriptiontemplatedefinition/DefaultValueBuilder.java b/backend/core/src/main/java/org/opencdmp/model/builder/descriptiontemplatedefinition/DefaultValueBuilder.java new file mode 100644 index 000000000..4aeaca76a --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/model/builder/descriptiontemplatedefinition/DefaultValueBuilder.java @@ -0,0 +1,66 @@ +package org.opencdmp.model.builder.descriptiontemplatedefinition; + +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.DataLogEntry; +import gr.cite.tools.logging.LoggerService; +import org.opencdmp.authorization.AuthorizationFlags; +import org.opencdmp.commons.enums.FieldType; +import org.opencdmp.commons.types.descriptiontemplate.DefaultValueEntity; +import org.opencdmp.convention.ConventionService; +import org.opencdmp.model.builder.BaseBuilder; +import org.opencdmp.model.descriptiontemplatedefinition.DefaultValue; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DefaultValueBuilder extends BaseBuilder { + + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + private org.opencdmp.commons.types.descriptiontemplate.FieldEntity fieldEntity; + + @Autowired + public DefaultValueBuilder( + ConventionService conventionService) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(DefaultValueBuilder.class))); + } + + public DefaultValueBuilder authorize(EnumSet values) { + this.authorize = values; + return this; + } + + public DefaultValueBuilder withFieldEntity(org.opencdmp.commons.types.descriptiontemplate.FieldEntity fieldEntity) { + this.fieldEntity = fieldEntity; + return this; + } + + @Override + public List build(FieldSet fields, List data) throws MyApplicationException { + this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0)); + this.logger.trace(new DataLogEntry("requested fields", fields)); + if (fields == null || data == null || fields.isEmpty()) + return new ArrayList<>(); + FieldType fieldType = this.fieldEntity != null && this.fieldEntity.getData() != null ? this.fieldEntity.getData().getFieldType() : FieldType.FREE_TEXT; + + List models = new ArrayList<>(); + for (DefaultValueEntity d : data) { + DefaultValue m = new DefaultValue(); + if (fields.hasField(this.asIndexer(DefaultValue._dateValue)) && FieldType.isDateType(fieldType)) m.setDateValue(d.getDateValue()); + if (fields.hasField(this.asIndexer(DefaultValue._booleanValue)) && FieldType.isBooleanType(fieldType)) m.setBooleanValue(d.getBooleanValue()); + if (fields.hasField(this.asIndexer(DefaultValue._textValue)) && FieldType.isTextType(fieldType)) m.setTextValue(d.getTextValue()); + if (fields.hasField(this.asIndexer(DefaultValue._textListValue)) && FieldType.isTextListType(fieldType)) m.setTextListValue(d.getTextListValue()); + + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } +} diff --git a/backend/core/src/main/java/org/opencdmp/model/builder/descriptiontemplatedefinition/FieldBuilder.java b/backend/core/src/main/java/org/opencdmp/model/builder/descriptiontemplatedefinition/FieldBuilder.java index 5172fe298..dfa6af4ae 100644 --- a/backend/core/src/main/java/org/opencdmp/model/builder/descriptiontemplatedefinition/FieldBuilder.java +++ b/backend/core/src/main/java/org/opencdmp/model/builder/descriptiontemplatedefinition/FieldBuilder.java @@ -1,26 +1,27 @@ package org.opencdmp.model.builder.descriptiontemplatedefinition; -import org.opencdmp.authorization.AuthorizationFlags; -import org.opencdmp.commons.types.descriptiontemplate.FieldEntity; -import org.opencdmp.convention.ConventionService; -import org.opencdmp.model.builder.BaseBuilder; -import org.opencdmp.service.fielddatahelper.FieldDataHelperService; -import org.opencdmp.service.fielddatahelper.FieldDataHelperServiceProvider; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.DataLogEntry; import gr.cite.tools.logging.LoggerService; +import org.opencdmp.authorization.AuthorizationFlags; +import org.opencdmp.commons.types.descriptiontemplate.FieldEntity; +import org.opencdmp.convention.ConventionService; +import org.opencdmp.model.builder.BaseBuilder; +import org.opencdmp.model.descriptiontemplatedefinition.Field; +import org.opencdmp.service.fielddatahelper.FieldDataHelperService; +import org.opencdmp.service.fielddatahelper.FieldDataHelperServiceProvider; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; -import org.opencdmp.model.descriptiontemplatedefinition.Field; + import java.util.*; @Component("descriptiontemplatedefinitionfieldbuilder") -@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class FieldBuilder extends BaseBuilder { private final BuilderFactory builderFactory; @@ -49,6 +50,7 @@ public class FieldBuilder extends BaseBuilder { //Not Bulk Build because is XML no interaction with db FieldSet visibilityRulesFields = fields.extractPrefixed(this.asPrefix(Field._visibilityRules)); + FieldSet defaultValueFields = fields.extractPrefixed(this.asPrefix(Field._defaultValue)); FieldSet dataFields = fields.extractPrefixed(this.asPrefix(Field._data)); List models = new ArrayList<>(); @@ -58,11 +60,11 @@ public class FieldBuilder extends BaseBuilder { if (fields.hasField(this.asIndexer(Field._ordinal))) m.setOrdinal(d.getOrdinal()); if (fields.hasField(this.asIndexer(Field._numbering))) m.setNumbering(d.getNumbering()); if (fields.hasField(this.asIndexer(Field._schematics))) m.setSchematics(d.getSchematics()); - if (fields.hasField(this.asIndexer(Field._defaultValue))) m.setDefaultValue(d.getDefaultValue()); if (fields.hasField(this.asIndexer(Field._includeInExport))) m.setIncludeInExport(d.getIncludeInExport()); if (fields.hasField(this.asIndexer(Field._validations))) m.setValidations(d.getValidations()); if (fields.hasField(this.asIndexer(Field._numbering))) m.setNumbering(d.getNumbering()); if (fields.hasField(this.asIndexer(Field._numbering))) m.setNumbering(d.getNumbering()); + if (!defaultValueFields.isEmpty() && d.getDefaultValue() != null) m.setDefaultValue(this.builderFactory.builder(DefaultValueBuilder.class).withFieldEntity(d).authorize(this.authorize).build(defaultValueFields, d.getDefaultValue())); if (!visibilityRulesFields.isEmpty() && d.getVisibilityRules() != null) m.setVisibilityRules(this.builderFactory.builder(RuleBuilder.class).withFieldEntity(d).authorize(this.authorize).build(visibilityRulesFields, d.getVisibilityRules())); if (!dataFields.isEmpty() && d.getData() != null){ FieldDataHelperService fieldDataHelperService = this.fieldDataHelperServiceProvider.get(d.getData().getFieldType()); diff --git a/backend/core/src/main/java/org/opencdmp/model/censorship/descriptiontemplatedefinition/DefaultValueCensor.java b/backend/core/src/main/java/org/opencdmp/model/censorship/descriptiontemplatedefinition/DefaultValueCensor.java new file mode 100644 index 000000000..517c0d991 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/model/censorship/descriptiontemplatedefinition/DefaultValueCensor.java @@ -0,0 +1,39 @@ +package org.opencdmp.model.censorship.descriptiontemplatedefinition; + +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.DataLogEntry; +import gr.cite.tools.logging.LoggerService; +import org.opencdmp.authorization.Permission; +import org.opencdmp.convention.ConventionService; +import org.opencdmp.model.censorship.BaseCensor; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DefaultValueCensor extends BaseCensor { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DefaultValueCensor.class)); + + protected final AuthorizationService authService; + + public DefaultValueCensor(ConventionService conventionService, + AuthorizationService authService) { + super(conventionService); + this.authService = authService; + } + + public void censor(FieldSet fields, UUID userId) { + logger.debug(new DataLogEntry("censoring fields", fields)); + if (fields == null || fields.isEmpty()) + return; + + this.authService.authorizeForce(Permission.BrowseDescriptionTemplate); + } + +} diff --git a/backend/core/src/main/java/org/opencdmp/model/censorship/descriptiontemplatedefinition/FieldCensor.java b/backend/core/src/main/java/org/opencdmp/model/censorship/descriptiontemplatedefinition/FieldCensor.java index e829f73f9..87b6a374d 100644 --- a/backend/core/src/main/java/org/opencdmp/model/censorship/descriptiontemplatedefinition/FieldCensor.java +++ b/backend/core/src/main/java/org/opencdmp/model/censorship/descriptiontemplatedefinition/FieldCensor.java @@ -1,23 +1,23 @@ package org.opencdmp.model.censorship.descriptiontemplatedefinition; -import org.opencdmp.authorization.Permission; -import org.opencdmp.convention.ConventionService; -import org.opencdmp.model.censorship.BaseCensor; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.censor.CensorFactory; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.DataLogEntry; import gr.cite.tools.logging.LoggerService; +import org.opencdmp.authorization.Permission; +import org.opencdmp.convention.ConventionService; +import org.opencdmp.model.censorship.BaseCensor; +import org.opencdmp.model.descriptiontemplatedefinition.Field; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; -import org.opencdmp.model.descriptiontemplatedefinition.Field; import java.util.UUID; @Component("descriptiontemplatedefinitionfieldcensor") -@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class FieldCensor extends BaseCensor { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(FieldCensor.class)); @@ -39,9 +39,12 @@ public class FieldCensor extends BaseCensor { this.authService.authorizeForce(Permission.BrowseDescriptionTemplate); - FieldSet multiplicityFields = fields.extractPrefixed(this.asIndexerPrefix(Field._visibilityRules)); - this.censorFactory.censor(RuleCensor.class).censor(multiplicityFields, userId); + FieldSet visibilityRulesFields = fields.extractPrefixed(this.asIndexerPrefix(Field._visibilityRules)); + this.censorFactory.censor(RuleCensor.class).censor(visibilityRulesFields, userId); + FieldSet defaultValueFields = fields.extractPrefixed(this.asIndexerPrefix(Field._defaultValue)); + this.censorFactory.censor(DefaultValueCensor.class).censor(defaultValueFields, userId); + FieldSet fieldFields = fields.extractPrefixed(this.asIndexerPrefix(Field._data)); this.censorFactory.censor(FieldDataCensor.class).censor(fieldFields, userId); } diff --git a/backend/core/src/main/java/org/opencdmp/model/descriptiontemplatedefinition/DefaultValue.java b/backend/core/src/main/java/org/opencdmp/model/descriptiontemplatedefinition/DefaultValue.java new file mode 100644 index 000000000..456126472 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/model/descriptiontemplatedefinition/DefaultValue.java @@ -0,0 +1,53 @@ +package org.opencdmp.model.descriptiontemplatedefinition; + +import java.time.Instant; +import java.util.List; + +public class DefaultValue { + + private String textValue; + public static final String _textValue = "textValue"; + + private List textListValue; + public static final String _textListValue = "textListValue"; + + private Instant dateValue; + public static final String _dateValue = "dateValue"; + + private Boolean booleanValue; + public static final String _booleanValue = "booleanValue"; + + + public String getTextValue() { + return this.textValue; + } + + public void setTextValue(String textValue) { + this.textValue = textValue; + } + + public List getTextListValue() { + return this.textListValue; + } + + public void setTextListValue(List textListValue) { + this.textListValue = textListValue; + } + + public Instant getDateValue() { + return this.dateValue; + } + + public void setDateValue(Instant dateValue) { + this.dateValue = dateValue; + } + + public Boolean getBooleanValue() { + return this.booleanValue; + } + + public void setBooleanValue(Boolean booleanValue) { + this.booleanValue = booleanValue; + } + +} diff --git a/backend/core/src/main/java/org/opencdmp/model/descriptiontemplatedefinition/Field.java b/backend/core/src/main/java/org/opencdmp/model/descriptiontemplatedefinition/Field.java index 0dc50b7a6..8f2240307 100644 --- a/backend/core/src/main/java/org/opencdmp/model/descriptiontemplatedefinition/Field.java +++ b/backend/core/src/main/java/org/opencdmp/model/descriptiontemplatedefinition/Field.java @@ -1,6 +1,5 @@ package org.opencdmp.model.descriptiontemplatedefinition; -import org.opencdmp.commons.enums.FieldType; import org.opencdmp.commons.enums.FieldValidationType; import org.opencdmp.model.descriptiontemplatedefinition.fielddata.BaseFieldData; @@ -21,7 +20,7 @@ public class Field { private List schematics; public final static String _defaultValue = "defaultValue"; - private String defaultValue; + private DefaultValue defaultValue; public final static String _visibilityRules = "visibilityRules"; private List visibilityRules; @@ -36,7 +35,7 @@ public class Field { private BaseFieldData data; public String getId() { - return id; + return this.id; } public void setId(String id) { @@ -44,7 +43,7 @@ public class Field { } public Integer getOrdinal() { - return ordinal; + return this.ordinal; } public void setOrdinal(Integer ordinal) { @@ -52,7 +51,7 @@ public class Field { } public String getNumbering() { - return numbering; + return this.numbering; } public void setNumbering(String numbering) { @@ -60,23 +59,23 @@ public class Field { } public List getSchematics() { - return schematics; + return this.schematics; } public void setSchematics(List schematics) { this.schematics = schematics; } - public String getDefaultValue() { - return defaultValue; + public DefaultValue getDefaultValue() { + return this.defaultValue; } - public void setDefaultValue(String defaultValue) { + public void setDefaultValue(DefaultValue defaultValue) { this.defaultValue = defaultValue; } public List getVisibilityRules() { - return visibilityRules; + return this.visibilityRules; } public void setVisibilityRules(List visibilityRules) { @@ -84,7 +83,7 @@ public class Field { } public List getValidations() { - return validations; + return this.validations; } public void setValidations(List validations) { @@ -92,7 +91,7 @@ public class Field { } public Boolean getIncludeInExport() { - return includeInExport; + return this.includeInExport; } public void setIncludeInExport(Boolean includeInExport) { @@ -100,7 +99,7 @@ public class Field { } public BaseFieldData getData() { - return data; + return this.data; } public void setData(BaseFieldData data) { diff --git a/backend/core/src/main/java/org/opencdmp/model/mapper/publicapi/DescriptionFieldToDatasetFieldMapper.java b/backend/core/src/main/java/org/opencdmp/model/mapper/publicapi/DescriptionFieldToDatasetFieldMapper.java index 08732590b..1c1fe79be 100644 --- a/backend/core/src/main/java/org/opencdmp/model/mapper/publicapi/DescriptionFieldToDatasetFieldMapper.java +++ b/backend/core/src/main/java/org/opencdmp/model/mapper/publicapi/DescriptionFieldToDatasetFieldMapper.java @@ -19,7 +19,7 @@ public class DescriptionFieldToDatasetFieldMapper { model.setDatatype(field.getData().getFieldType().name()); DefaultValueEntity defaultValueEntity = new DefaultValueEntity(); defaultValueEntity.setType(field.getData().getFieldType().name()); - defaultValueEntity.setValue(field.getDefaultValue()); + defaultValueEntity.setValue(field.getDefaultValue() != null ? field.getDefaultValue().getTextValue(): null); //TODO model.setDefaultValue(defaultValueEntity); model.setExport(field.getIncludeInExport()); model.setNumbering(field.getNumbering()); diff --git a/backend/core/src/main/java/org/opencdmp/model/persist/descriptiontemplatedefinition/DefaultValuePersist.java b/backend/core/src/main/java/org/opencdmp/model/persist/descriptiontemplatedefinition/DefaultValuePersist.java new file mode 100644 index 000000000..058a7ba71 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/model/persist/descriptiontemplatedefinition/DefaultValuePersist.java @@ -0,0 +1,85 @@ +package org.opencdmp.model.persist.descriptiontemplatedefinition; + +import gr.cite.tools.validation.specification.Specification; +import org.opencdmp.commons.validation.BaseValidator; +import org.opencdmp.convention.ConventionService; +import org.opencdmp.errorcode.ErrorThesaurusProperties; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.time.Instant; +import java.util.Arrays; +import java.util.List; + +public class DefaultValuePersist { + + + private String textValue; + public static final String _textValue = "textValue"; + + private List textListValue; + public static final String _textListValue = "textListValue"; + + private Instant dateValue; + public static final String _dateValue = "dateValue"; + + private Boolean booleanValue; + public static final String _booleanValue = "booleanValue"; + + public String getTextValue() { + return this.textValue; + } + + public void setTextValue(String textValue) { + this.textValue = textValue; + } + + public List getTextListValue() { + return this.textListValue; + } + + public void setTextListValue(List textListValue) { + this.textListValue = textListValue; + } + + public Instant getDateValue() { + return this.dateValue; + } + + public void setDateValue(Instant dateValue) { + this.dateValue = dateValue; + } + + public Boolean getBooleanValue() { + return this.booleanValue; + } + + public void setBooleanValue(Boolean booleanValue) { + this.booleanValue = booleanValue; + } + + @Component(DefaultValuePersistValidator.ValidatorName) + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public static class DefaultValuePersistValidator extends BaseValidator { + + public static final String ValidatorName = "DescriptionTemplate.DefaultValuePersistValidator"; + + protected DefaultValuePersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors) { + super(conventionService, errors); + } + + + @Override + protected Class modelClass() { + return DefaultValuePersist.class; + } + + @Override + protected List specifications(DefaultValuePersist item) { + return Arrays.asList( + ); + } + } + +} diff --git a/backend/core/src/main/java/org/opencdmp/model/persist/descriptiontemplatedefinition/FieldPersist.java b/backend/core/src/main/java/org/opencdmp/model/persist/descriptiontemplatedefinition/FieldPersist.java index e51af5777..96b815210 100644 --- a/backend/core/src/main/java/org/opencdmp/model/persist/descriptiontemplatedefinition/FieldPersist.java +++ b/backend/core/src/main/java/org/opencdmp/model/persist/descriptiontemplatedefinition/FieldPersist.java @@ -1,12 +1,12 @@ package org.opencdmp.model.persist.descriptiontemplatedefinition; -import org.opencdmp.commons.enums.FieldValidationType; -import org.opencdmp.commons.validation.BaseValidator; import gr.cite.tools.validation.ValidatorFactory; import gr.cite.tools.validation.specification.Specification; +import org.opencdmp.commons.enums.FieldValidationType; +import org.opencdmp.commons.validation.BaseValidator; import org.opencdmp.convention.ConventionService; import org.opencdmp.errorcode.ErrorThesaurusProperties; -import org.opencdmp.model.persist.descriptiontemplatedefinition.fielddata.*; +import org.opencdmp.model.persist.descriptiontemplatedefinition.fielddata.BaseFieldDataPersist; import org.opencdmp.service.fielddatahelper.FieldDataHelperServiceProvider; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.MessageSource; @@ -19,17 +19,18 @@ import java.util.List; public class FieldPersist { - private String id = null; + private String id; public static final String _id = "id"; - private Integer ordinal = null; + private Integer ordinal; public static final String _ordinal = "ordinal"; private List schematics; - private String defaultValue; + private DefaultValuePersist defaultValue; + public static final String _defaultValue = "defaultValue"; private List visibilityRules; @@ -37,16 +38,16 @@ public class FieldPersist { private List validations; - private Boolean includeInExport = null; + private Boolean includeInExport; public static final String _includeInExport = "includeInExport"; - private BaseFieldDataPersist data = null; + private BaseFieldDataPersist data; public static final String _data = "data"; public String getId() { - return id; + return this.id; } public void setId(String id) { @@ -54,7 +55,7 @@ public class FieldPersist { } public Integer getOrdinal() { - return ordinal; + return this.ordinal; } public void setOrdinal(Integer ordinal) { @@ -62,23 +63,23 @@ public class FieldPersist { } public List getSchematics() { - return schematics; + return this.schematics; } public void setSchematics(List schematics) { this.schematics = schematics; } - public String getDefaultValue() { - return defaultValue; + public DefaultValuePersist getDefaultValue() { + return this.defaultValue; } - public void setDefaultValue(String defaultValue) { + public void setDefaultValue(DefaultValuePersist defaultValue) { this.defaultValue = defaultValue; } public List getVisibilityRules() { - return visibilityRules; + return this.visibilityRules; } public void setVisibilityRules(List visibilityRules) { @@ -86,7 +87,7 @@ public class FieldPersist { } public List getValidations() { - return validations; + return this.validations; } public void setValidations(List validations) { @@ -94,7 +95,7 @@ public class FieldPersist { } public Boolean getIncludeInExport() { - return includeInExport; + return this.includeInExport; } public void setIncludeInExport(Boolean includeInExport) { @@ -102,7 +103,7 @@ public class FieldPersist { } public BaseFieldDataPersist getData() { - return data; + return this.data; } public void setData(BaseFieldDataPersist data) { @@ -137,19 +138,24 @@ public class FieldPersist { return Arrays.asList( this.spec() .must(() -> !this.isEmpty(item.getId())) - .failOn(FieldPersist._id).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._id}, LocaleContextHolder.getLocale())), + .failOn(FieldPersist._id).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._id}, LocaleContextHolder.getLocale())), this.spec() .must(() -> !this.isNull(item.getOrdinal())) - .failOn(FieldPersist._ordinal).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._ordinal}, LocaleContextHolder.getLocale())), + .failOn(FieldPersist._ordinal).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._ordinal}, LocaleContextHolder.getLocale())), this.spec() .must(() -> !this.isNull(item.getIncludeInExport())) - .failOn(FieldPersist._includeInExport).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._includeInExport}, LocaleContextHolder.getLocale())), + .failOn(FieldPersist._includeInExport).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._includeInExport}, LocaleContextHolder.getLocale())), this.navSpec() .iff(() -> !this.isListNullOrEmpty(item.getVisibilityRules())) .on(FieldPersist._visibilityRules) .over(item.getVisibilityRules()) .using((itm) -> this.validatorFactory.validator(RulePersist.RulePersistValidator.class).withFieldPersist(item)), + this.refSpec() + .iff(() -> !this.isNull(item.getDefaultValue())) + .on(FieldPersist._defaultValue) + .over(item.getDefaultValue()) + .using(() -> this.validatorFactory.validator(DefaultValuePersist.DefaultValuePersistValidator.class)), this.refSpec() .iff(() -> !this.isNull(item.getData()) && item.getData().getFieldType() != null) .on(FieldPersist._data) @@ -158,7 +164,7 @@ public class FieldPersist { this.spec() .iff(() -> !this.isNull(item.getData())) .must(() -> !this.isNull(item.getData().getFieldType())) - .failOn(FieldPersist._data + '.' + BaseFieldDataPersist._fieldType).failWith(messageSource.getMessage("Validation_Required", new Object[]{BaseFieldDataPersist._fieldType}, LocaleContextHolder.getLocale())) + .failOn(FieldPersist._data + '.' + BaseFieldDataPersist._fieldType).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{BaseFieldDataPersist._fieldType}, LocaleContextHolder.getLocale())) ); } } diff --git a/backend/core/src/main/java/org/opencdmp/model/publicapi/datasetwizard/Field.java b/backend/core/src/main/java/org/opencdmp/model/publicapi/datasetwizard/Field.java index 0f255304a..f5e21474c 100644 --- a/backend/core/src/main/java/org/opencdmp/model/publicapi/datasetwizard/Field.java +++ b/backend/core/src/main/java/org/opencdmp/model/publicapi/datasetwizard/Field.java @@ -2,11 +2,11 @@ package org.opencdmp.model.publicapi.datasetwizard; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.NotImplementedException; +import org.json.JSONException; import org.opencdmp.commons.enums.FieldValidationType; import org.opencdmp.commons.types.descriptiontemplate.FieldEntity; import org.opencdmp.commons.types.descriptiontemplate.MultiplicityEntity; -import org.apache.commons.lang3.NotImplementedException; -import org.json.JSONException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,7 +37,7 @@ public class Field implements Comparable, PropertiesModelBuilder { private Boolean export; public List getMultiplicityItems() { - return multiplicityItems; + return this.multiplicityItems; } public void setMultiplicityItems(List multiplicityItems) { @@ -49,7 +49,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public String getId() { - return id; + return this.id; } public void setId(String id) { @@ -57,7 +57,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public Integer getOrdinal() { - return ordinal; + return this.ordinal; } public void setOrdinal(int ordinal) { @@ -65,7 +65,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public Object getValue() { - return value; + return this.value; } public void setValue(Object value) { @@ -73,7 +73,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public FieldDescriptionEntity getViewStyle() { - return viewStyle; + return this.viewStyle; } public void setViewStyle(FieldDescriptionEntity viewStyle) { @@ -81,7 +81,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public int getPage() { - return page; + return this.page; } public void setPage(int page) { @@ -89,7 +89,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public DefaultValueEntity getDefaultValue() { - return defaultValue; + return this.defaultValue; } public void setDefaultValue(DefaultValueEntity defaultValue) { @@ -97,7 +97,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public String getDatatype() { - return datatype; + return this.datatype; } public void setDatatype(String datatype) { @@ -105,7 +105,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public MultiplicityEntity getMultiplicity() { - return multiplicity; + return this.multiplicity; } public void setMultiplicity(MultiplicityEntity multiplicity) { @@ -113,7 +113,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public Object getData() { - return data; + return this.data; } public void setData(Object data) { @@ -121,7 +121,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public VisibilityEntity getVisible() { - return visible; + return this.visible; } public void setVisible(VisibilityEntity visible) { @@ -140,7 +140,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public String getNumbering() { - return numbering; + return this.numbering; } public void setNumbering(String numbering) { @@ -148,7 +148,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public List getSchematics() { - return schematics; + return this.schematics; } public void setSchematics(List schematics) { @@ -156,7 +156,7 @@ public class Field implements Comparable, PropertiesModelBuilder { } public Boolean getExport() { - return export; + return this.export; } public void setExport(Boolean export) { @@ -204,7 +204,7 @@ public class Field implements Comparable, PropertiesModelBuilder { this.data = item.getData(); DefaultValueEntity defaultValueEntity = new DefaultValueEntity(); - defaultValueEntity.setValue(item.getDefaultValue()); + defaultValueEntity.setValue(item.getDefaultValue().getTextValue()); //TODO this.defaultValue = defaultValueEntity; VisibilityEntity visibilityEntity = new VisibilityEntity(); visibilityEntity.setRules(item.getVisibilityRules()); diff --git a/backend/core/src/main/java/org/opencdmp/service/descriptiontemplate/DescriptionTemplateServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/descriptiontemplate/DescriptionTemplateServiceImpl.java index efc5b3d67..b2d441bab 100644 --- a/backend/core/src/main/java/org/opencdmp/service/descriptiontemplate/DescriptionTemplateServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/descriptiontemplate/DescriptionTemplateServiceImpl.java @@ -367,12 +367,12 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic data.setOrdinal(persist.getOrdinal()); data.setSchematics(persist.getSchematics()); //data.setNumbering(persist.get()); //TODO - data.setDefaultValue(persist.getDefaultValue()); data.setValidations(persist.getValidations()); data.setIncludeInExport(persist.getIncludeInExport()); if (persist.getData() != null) data.setData(this.buildFieldDataEntity(persist.getData())); + data.setDefaultValue(this.buildDefaultValueEntity(persist.getDefaultValue(), data)); if (!this.conventionService.isListNullOrEmpty(persist.getVisibilityRules())) { data.setVisibilityRules(new ArrayList<>()); for (RulePersist fieldPersist : persist.getVisibilityRules()) { @@ -427,6 +427,43 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic return data; } + + private @NotNull DefaultValueEntity buildDefaultValueEntity(DefaultValuePersist persist, FieldEntity fieldEntity) { + FieldType fieldType = fieldEntity != null && fieldEntity.getData() != null ? fieldEntity.getData().getFieldType() : FieldType.FREE_TEXT; + DefaultValueEntity data = new DefaultValueEntity(); + if (persist == null) return data; + + if (FieldType.isTextType(fieldType)) { + if (FieldType.UPLOAD.equals(fieldType) && !this.conventionService.isNullOrEmpty(persist.getTextValue())){ + throw new NotImplementedException("Upload not supported"); + } else { + data.setTextValue(persist.getTextValue()); + } + } + else if (FieldType.isTextListType(fieldType)) { + if (FieldType.INTERNAL_ENTRIES_DMPS.equals(fieldType) && !this.conventionService.isListNullOrEmpty(persist.getTextListValue())){ + throw new NotImplementedException("dmps not supported"); + + } + if (FieldType.INTERNAL_ENTRIES_DESCRIPTIONS.equals(fieldType) && !this.conventionService.isListNullOrEmpty(persist.getTextListValue())){ + throw new NotImplementedException("descriptions not supported"); + } + if (FieldType.TAGS.equals(fieldType) && !this.conventionService.isListNullOrEmpty(persist.getTextListValue())){ + throw new NotImplementedException("tags not supported"); + } + data.setTextListValue(persist.getTextListValue()); + } + else if (FieldType.isReferenceType(fieldType) ) { + throw new NotImplementedException("reference not supported"); + } + else if (FieldType.isDateType(fieldType)) data.setDateValue(persist.getDateValue()); + else if (FieldType.isBooleanType(fieldType)) data.setBooleanValue(persist.getBooleanValue()); + else if (FieldType.isExternalIdentifierType(fieldType)){ + throw new NotImplementedException("external identifier not supported"); + } + + return data; + } private @NotNull ExternalIdentifierEntity buildExternalIdentifierEntity(ExternalIdentifierPersist persist){ ExternalIdentifierEntity data = new ExternalIdentifierEntity(); if (persist == null) return data; @@ -846,7 +883,7 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic fieldEntity.setId(importExport.getId()); fieldEntity.setOrdinal(importExport.getOrdinal()); fieldEntity.setValidations(importExport.getValidations()); - fieldEntity.setDefaultValue(importExport.getDefaultValue()); + fieldEntity.setDefaultValue(this.toRuleModel(importExport.getDefaultValue())); List rulePersists = new ArrayList<>(); if (importExport.getVisibilityRules() != null) { for (DescriptionTemplateRuleImportExport xmlRule : importExport.getVisibilityRules()) { @@ -875,6 +912,16 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic return ruleEntity; } + public DefaultValuePersist toRuleModel(DescriptionTemplateDefaultValueImportExport importExport) { + if (importExport == null) return null; + DefaultValuePersist ruleEntity = new DefaultValuePersist(); + ruleEntity.setDateValue(importExport.getDateValue()); + ruleEntity.setBooleanValue(importExport.getBooleanValue()); + ruleEntity.setTextValue(importExport.getTextValue()); + ruleEntity.setTextListValue(importExport.getTextListValue()); + return ruleEntity; + } + public MultiplicityPersist xmlMultiplicityToPersist(DescriptionTemplateMultiplicityImportExport importXml) { MultiplicityPersist multiplicityEntity = new MultiplicityPersist(); multiplicityEntity.setMax(importXml.getMax()); @@ -999,7 +1046,7 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic xml.setId(entity.getId()); xml.setOrdinal(entity.getOrdinal()); xml.setValidations(entity.getValidations()); - xml.setDefaultValue(entity.getDefaultValue()); + xml.setDefaultValue(this.toDefaultValueModel(entity.getDefaultValue())); List rulePersists = new ArrayList<>(); if (!this.conventionService.isListNullOrEmpty(entity.getVisibilityRules())) { for (RuleEntity xmlRule : entity.getVisibilityRules()) { @@ -1017,6 +1064,15 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic return xml; } + private DescriptionTemplateDefaultValueImportExport toDefaultValueModel(DefaultValueEntity entity) { + DescriptionTemplateDefaultValueImportExport xml = new DescriptionTemplateDefaultValueImportExport(); + xml.setDateValue(entity.getDateValue()); + xml.setBooleanValue(entity.getBooleanValue()); + xml.setTextListValue(entity.getTextListValue()); + xml.setTextValue(entity.getTextValue()); + return xml; + } + private DescriptionTemplateRuleImportExport toRuleModel(RuleEntity entity) { DescriptionTemplateRuleImportExport xml = new DescriptionTemplateRuleImportExport(); xml.setTarget(entity.getTarget()); diff --git a/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderService.java b/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderService.java new file mode 100644 index 000000000..b4afc1c0a --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderService.java @@ -0,0 +1,7 @@ +package org.opencdmp.service.fieldsetexpander; + +import gr.cite.tools.fieldset.FieldSet; + +public interface FieldSetExpanderService { + FieldSet expand(FieldSet fieldSet); +} diff --git a/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceConfiguration.java b/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceConfiguration.java new file mode 100644 index 000000000..0162efbf0 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceConfiguration.java @@ -0,0 +1,18 @@ +package org.opencdmp.service.fieldsetexpander; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableConfigurationProperties(FieldSetExpanderServiceProperties.class) +public class FieldSetExpanderServiceConfiguration { + private final FieldSetExpanderServiceProperties expanderServiceProperties; + + public FieldSetExpanderServiceConfiguration(FieldSetExpanderServiceProperties expanderServiceProperties) { + this.expanderServiceProperties = expanderServiceProperties; + } + + public FieldSetExpanderServiceProperties getExpanderServiceProperties() { + return this.expanderServiceProperties; + } +} diff --git a/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceImpl.java new file mode 100644 index 000000000..63a69f901 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceImpl.java @@ -0,0 +1,36 @@ +package org.opencdmp.service.fieldsetexpander; + +import gr.cite.tools.fieldset.FieldSet; +import org.opencdmp.convention.ConventionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; + +@Service +public class FieldSetExpanderServiceImpl implements FieldSetExpanderService { + + + private final ConventionService conventionService; + private final FieldSetExpanderServiceConfiguration fieldSetExpanderServiceConfiguration; + @Autowired + public FieldSetExpanderServiceImpl( + ConventionService conventionService, FieldSetExpanderServiceConfiguration fieldSetExpanderServiceConfiguration) { + this.conventionService = conventionService; + this.fieldSetExpanderServiceConfiguration = fieldSetExpanderServiceConfiguration; + } + + @Override + public FieldSet expand(FieldSet fieldSet) { + if (fieldSet == null) return null; + if (this.fieldSetExpanderServiceConfiguration == null || this.fieldSetExpanderServiceConfiguration.getExpanderServiceProperties() == null || this.conventionService.isListNullOrEmpty(this.fieldSetExpanderServiceConfiguration.getExpanderServiceProperties().getMappings())) return fieldSet; + List fields = new ArrayList<>(fieldSet.getFields()); + + for (String field : fields) { + FieldSetExpanderServiceProperties.Mapping mapping = this.fieldSetExpanderServiceConfiguration.getExpanderServiceProperties().getMappings().stream().filter(x -> x.getKey().equalsIgnoreCase(field)).findFirst().orElse(null); + if (mapping != null && !this.conventionService.isListNullOrEmpty(mapping.getFields())) fieldSet.ensure(mapping.getFields().toArray(new String[0])); + } + return fieldSet; + } +} diff --git a/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceProperties.java b/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceProperties.java new file mode 100644 index 000000000..43288dd2c --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/service/fieldsetexpander/FieldSetExpanderServiceProperties.java @@ -0,0 +1,47 @@ +package org.opencdmp.service.fieldsetexpander; + + +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.List; + +@ConfigurationProperties(prefix = "field-set-expander") +public class FieldSetExpanderServiceProperties { + private List mappings; + + public FieldSetExpanderServiceProperties() { + } + + public List getMappings() { + return this.mappings; + } + + public void setMappings(List mappings) { + this.mappings = mappings; + } + + public static class Mapping { + private List fields; + private String key; + + public Mapping() { + } + + public List getFields() { + return this.fields; + } + + public void setFields(List fields) { + this.fields = fields; + } + + public String getKey() { + return this.key; + } + + public void setKey(String key) { + this.key = key; + } + } +} + diff --git a/backend/web/src/main/java/org/opencdmp/controllers/DescriptionController.java b/backend/web/src/main/java/org/opencdmp/controllers/DescriptionController.java index 405be58d4..727ad05ec 100644 --- a/backend/web/src/main/java/org/opencdmp/controllers/DescriptionController.java +++ b/backend/web/src/main/java/org/opencdmp/controllers/DescriptionController.java @@ -31,6 +31,7 @@ import org.opencdmp.query.DmpQuery; import org.opencdmp.query.lookup.DescriptionLookup; import org.opencdmp.service.description.DescriptionService; import org.opencdmp.service.elastic.ElasticQueryHelperService; +import org.opencdmp.service.fieldsetexpander.FieldSetExpanderService; import org.opencdmp.service.storage.StorageFileService; import org.slf4j.LoggerFactory; import org.springframework.context.MessageSource; @@ -77,6 +78,7 @@ public class DescriptionController { private final ElasticQueryHelperService elasticQueryHelperService; private final StorageFileService storageFileService; private final ConventionService conventionService; + private final FieldSetExpanderService fieldSetExpanderService; public DescriptionController( BuilderFactory builderFactory, AuditService auditService, @@ -84,7 +86,7 @@ public class DescriptionController { CensorFactory censorFactory, QueryFactory queryFactory, MessageSource messageSource, - ElasticQueryHelperService elasticQueryHelperService, StorageFileService storageFileService, ConventionService conventionService) { + ElasticQueryHelperService elasticQueryHelperService, StorageFileService storageFileService, ConventionService conventionService, FieldSetExpanderService fieldSetExpanderService) { this.builderFactory = builderFactory; this.auditService = auditService; this.descriptionService = descriptionService; @@ -94,6 +96,7 @@ public class DescriptionController { this.elasticQueryHelperService = elasticQueryHelperService; this.storageFileService = storageFileService; this.conventionService = conventionService; + this.fieldSetExpanderService = fieldSetExpanderService; } @PostMapping("public/query") @@ -111,9 +114,10 @@ public class DescriptionController { } @GetMapping("public/{id}") - public PublicDescription publicGet(@PathVariable("id") UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException { + public PublicDescription publicGet(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException { logger.debug(new MapLogEntry("retrieving" + PublicDescription.class.getSimpleName()).And("id", id).And("fields", fieldSet)); - + fieldSet = this.fieldSetExpanderService.expand(fieldSet); + this.censorFactory.censor(PublicDescriptionCensor.class).censor(fieldSet); DescriptionQuery query = this.queryFactory.query(DescriptionQuery.class).authorize(EnumSet.of(Public)).ids(id).dmpSubQuery(this.queryFactory.query(DmpQuery.class).isActive(IsActive.Active).statuses(DmpStatus.Finalized).accessTypes(DmpAccessType.Public)); @@ -144,8 +148,9 @@ public class DescriptionController { @GetMapping("{id}") - public Description get(@PathVariable("id") UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException { + public Description get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException { logger.debug(new MapLogEntry("retrieving" + Description.class.getSimpleName()).And("id", id).And("fields", fieldSet)); + fieldSet = this.fieldSetExpanderService.expand(fieldSet); this.censorFactory.censor(DescriptionCensor.class).censor(fieldSet, null); @@ -167,6 +172,8 @@ public class DescriptionController { @ValidationFilterAnnotation(validator = DescriptionPersist.DescriptionPersistValidator.ValidatorName, argumentName = "model") public Description persist(@RequestBody DescriptionPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException, IOException { logger.debug(new MapLogEntry("persisting" + Description.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet)); + fieldSet = this.fieldSetExpanderService.expand(fieldSet); + Description persisted = this.descriptionService.persist(model, fieldSet); this.auditService.track(AuditableAction.Description_Persist, Map.ofEntries( @@ -182,6 +189,8 @@ public class DescriptionController { @ValidationFilterAnnotation(validator = DescriptionStatusPersist.DescriptionStatusPersistValidator.ValidatorName, argumentName = "model") public Description persistStatus(@RequestBody DescriptionStatusPersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, IOException, InvalidApplicationException { logger.debug(new MapLogEntry("persisting" + Description.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet)); + fieldSet = this.fieldSetExpanderService.expand(fieldSet); + Description persisted = this.descriptionService.persistStatus(model, fieldSet); this.auditService.track(AuditableAction.Description_PersistStatus, Map.ofEntries( @@ -242,6 +251,8 @@ public class DescriptionController { @ValidationFilterAnnotation(validator = DescriptionFieldFilePersist.PersistValidator.ValidatorName, argumentName = "model") public StorageFile uploadFieldFiles(@RequestParam("file") MultipartFile file, @RequestParam("model") DescriptionFieldFilePersist model, FieldSet fieldSet) throws IOException { logger.debug(new MapLogEntry("uploadFieldFiles" + Description.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet)); + fieldSet = this.fieldSetExpanderService.expand(fieldSet); + StorageFile persisted = this.descriptionService.uploadFieldFile(model, file, fieldSet); this.auditService.track(AuditableAction.Description_UploadFieldFiles, Map.ofEntries( diff --git a/backend/web/src/main/java/org/opencdmp/controllers/publicapi/PublicDatasetsDescriptionDocumentation.java b/backend/web/src/main/java/org/opencdmp/controllers/publicapi/PublicDatasetsDescriptionDocumentation.java index 4a7964001..ad98285b0 100644 --- a/backend/web/src/main/java/org/opencdmp/controllers/publicapi/PublicDatasetsDescriptionDocumentation.java +++ b/backend/web/src/main/java/org/opencdmp/controllers/publicapi/PublicDatasetsDescriptionDocumentation.java @@ -184,7 +184,10 @@ public class PublicDatasetsDescriptionDocumentation { String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._data, BaseFieldData._label), String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._data, BaseFieldData._fieldType), String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._schematics), - String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._defaultValue), + String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._defaultValue, DefaultValue._dateValue), + String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._defaultValue, DefaultValue._booleanValue), + String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._defaultValue, DefaultValue._textListValue), + String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._defaultValue, DefaultValue._textValue), String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._includeInExport), String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._validations), String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._visibilityRules, Rule._target), diff --git a/backend/web/src/main/resources/config/application.yml b/backend/web/src/main/resources/config/application.yml index 9f5af550c..f9c7cbefa 100644 --- a/backend/web/src/main/resources/config/application.yml +++ b/backend/web/src/main/resources/config/application.yml @@ -31,6 +31,7 @@ spring: optional:classpath:config/file-transformer.yml[.yml], optional:classpath:config/file-transformer-${spring.profiles.active}.yml[.yml], optional:file:../config/file-transformer-${spring.profiles.active}.yml[.yml], optional:classpath:config/authorization.yml[.yml], optional:classpath:config/authorization-${spring.profiles.active}.yml[.yml], optional:file:../config/authorization-${spring.profiles.active}.yml[.yml], optional:classpath:config/metrics.yml[.yml], optional:classpath:config/metrics-${spring.profiles.active}.yml[.yml], optional:file:../config/metrics-${spring.profiles.active}.yml[.yml], + optional:classpath:config/field-set-expander.yml[.yml], optional:classpath:config/field-set-expander-${spring.profiles.active}.yml[.yml], optional:file:../config/field-set-expander-${spring.profiles.active}.yml[.yml], optional:classpath:config/lock.yml[.yml], optional:classpath:config/lock-${spring.profiles.active}.yml[.yml], optional:file:../config/lock-${spring.profiles.active}.yml[.yml] diff --git a/backend/web/src/main/resources/config/field-set-expander.yml b/backend/web/src/main/resources/config/field-set-expander.yml new file mode 100644 index 000000000..bec2f561a --- /dev/null +++ b/backend/web/src/main/resources/config/field-set-expander.yml @@ -0,0 +1,53 @@ +fieldSetExpander: + mappings: + - key: DescriptionEditorDescriptionTemplateLookupFields + fields: + - descriptionTemplate.id + - descriptionTemplate.label + - descriptionTemplate.version + - descriptionTemplate.versionStatus + - descriptionTemplate.groupId + - descriptionTemplate.isActive + - descriptionTemplate.definition.pages.id + - descriptionTemplate.definition.pages.ordinal + - descriptionTemplate.definition.pages.title + - descriptionTemplate.definition.pages.sections.id + - descriptionTemplate.definition.pages.sections.ordinal + - descriptionTemplate.definition.pages.sections.title + - descriptionTemplate.definition.pages.sections.description + - descriptionTemplate.definition.pages.sections.sections + - descriptionTemplate.definition.pages.sections.fieldSets.id + - descriptionTemplate.definition.pages.sections.fieldSets.ordinal + - descriptionTemplate.definition.pages.sections.fieldSets.title + - descriptionTemplate.definition.pages.sections.fieldSets.description + - descriptionTemplate.definition.pages.sections.fieldSets.extendedDescription + - descriptionTemplate.definition.pages.sections.fieldSets.additionalInformation + - descriptionTemplate.definition.pages.sections.fieldSets.hasCommentField + - descriptionTemplate.definition.pages.sections.fieldSets.hasMultiplicity + - descriptionTemplate.definition.pages.sections.fieldSets.multiplicity.min + - descriptionTemplate.definition.pages.sections.fieldSets.multiplicity.max + - descriptionTemplate.definition.pages.sections.fieldSets.multiplicity.placeholder + - descriptionTemplate.definition.pages.sections.fieldSets.multiplicity.tableView + - descriptionTemplate.definition.pages.sections.fieldSets.fields.id + - descriptionTemplate.definition.pages.sections.fieldSets.fields.defaultValue.textValue + - descriptionTemplate.definition.pages.sections.fieldSets.fields.defaultValue.textListValue + - descriptionTemplate.definition.pages.sections.fieldSets.fields.defaultValue.dateValue + - descriptionTemplate.definition.pages.sections.fieldSets.fields.defaultValue.booleanValue + - descriptionTemplate.definition.pages.sections.fieldSets.fields.validations + - descriptionTemplate.definition.pages.sections.fieldSets.fields.visibilityRules.target + - descriptionTemplate.definition.pages.sections.fieldSets.fields.visibilityRules.textValue + - descriptionTemplate.definition.pages.sections.fieldSets.fields.visibilityRules.textListValue + - descriptionTemplate.definition.pages.sections.fieldSets.fields.visibilityRules.dateValue + - descriptionTemplate.definition.pages.sections.fieldSets.fields.visibilityRules.booleanValue + - descriptionTemplate.definition.pages.sections.fieldSets.fields.data.label + - descriptionTemplate.definition.pages.sections.fieldSets.fields.data.fieldType + - descriptionTemplate.definition.pages.sections.fieldSets.fields.data.options.label + - descriptionTemplate.definition.pages.sections.fieldSets.fields.data.options.value + - descriptionTemplate.definition.pages.sections.fieldSets.fields.data.multipleSelect + - descriptionTemplate.definition.pages.sections.fieldSets.fields.data.type + - descriptionTemplate.definition.pages.sections.fieldSets.fields.data.maxFileSizeInMB + - descriptionTemplate.definition.pages.sections.fieldSets.fields.data.types.label + - descriptionTemplate.definition.pages.sections.fieldSets.fields.data.types.value + - descriptionTemplate.definition.pages.sections.fieldSets.fields.data.referenceType.id + - descriptionTemplate.definition.pages.sections.fieldSets.fields.data.referenceType.name + \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/description-template/description-template-persist.ts b/dmp-frontend/src/app/core/model/description-template/description-template-persist.ts index 298f1bb41..7500b1559 100644 --- a/dmp-frontend/src/app/core/model/description-template/description-template-persist.ts +++ b/dmp-frontend/src/app/core/model/description-template/description-template-persist.ts @@ -74,13 +74,20 @@ export interface DescriptionTemplateFieldPersist { id: string; ordinal: number; schematics: string[]; - defaultValue: string; + defaultValue: DescriptionTemplateDefaultValuePersist; visibilityRules: DescriptionTemplateRulePersist[]; validations: DescriptionTemplateFieldValidationType[]; includeInExport: boolean; data: DescriptionTemplateBaseFieldDataPersist; } +export interface DescriptionTemplateDefaultValuePersist { + textValue: string; + textListValue: string[]; + dateValue: Date; + booleanValue: boolean; +} + export interface DescriptionTemplateRulePersist { target: string; textValue: string; diff --git a/dmp-frontend/src/app/core/model/description-template/description-template.ts b/dmp-frontend/src/app/core/model/description-template/description-template.ts index aab1b3926..3af336f72 100644 --- a/dmp-frontend/src/app/core/model/description-template/description-template.ts +++ b/dmp-frontend/src/app/core/model/description-template/description-template.ts @@ -72,13 +72,21 @@ export interface DescriptionTemplateField { ordinal: number; numbering?: string; schematics?: string[]; - defaultValue?: string; + defaultValue?: DescriptionTemplateDefaultValue; visibilityRules?: DescriptionTemplateRule[]; validations?: DescriptionTemplateFieldValidationType[]; includeInExport: boolean; data?: DescriptionTemplateBaseFieldData; } +export interface DescriptionTemplateDefaultValue { + textValue: string; + textListValue: string[]; + dateValue: Date; + booleanValue: boolean; +} + + export interface DescriptionTemplateRule { target: string; textValue: string; diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/components/default-value/description-template-editor-default-value.component.html b/dmp-frontend/src/app/ui/admin/description-template/editor/components/default-value/description-template-editor-default-value.component.html index 13dd0f1dc..416bd66d0 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/components/default-value/description-template-editor-default-value.component.html +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/components/default-value/description-template-editor-default-value.component.html @@ -5,10 +5,10 @@ {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.NONE' | translate}} - {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.YES' + {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.YES' | translate}} - {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.NO' + {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.NO' | translate}} @@ -20,8 +20,8 @@ {{placeHolder}} - {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.CHECKED' | translate}} - {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.UNCHECKED' | translate}} + {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.CHECKED' | translate}} + {{'DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.CHECK-BOX.UNCHECKED' | translate}} {{form.getError('backendError').message}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -84,4 +84,4 @@ {{'GENERAL.VALIDATION.REQUIRED' | translate}} - \ No newline at end of file + diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/components/field/description-template-editor-field.component.html b/dmp-frontend/src/app/ui/admin/description-template/editor/components/field/description-template-editor-field.component.html index f7f5f1aba..810837903 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/components/field/description-template-editor-field.component.html +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/components/field/description-template-editor-field.component.html @@ -133,9 +133,20 @@ {{form.get('includeInExport').getError('backendError').message}} - - - + +
+ +
+
+ +
+
+ +
+
+ +
+
@@ -176,4 +187,4 @@
- \ No newline at end of file + diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/components/field/description-template-editor-field.component.ts b/dmp-frontend/src/app/ui/admin/description-template/editor/components/field/description-template-editor-field.component.ts index 474d251b4..f82c7dc32 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/components/field/description-template-editor-field.component.ts +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/components/field/description-template-editor-field.component.ts @@ -109,7 +109,12 @@ export class DescriptionTemplateEditorFieldComponent extends BaseComponent imple const type = this.fieldType; const field: DescriptionTemplateFieldPersist = this.form.getRawValue(); - field.defaultValue = undefined; + field.defaultValue = { + booleanValue: null, + dateValue: null, + textListValue: null, + textValue: null, + }; if (!this.canApplyVisibility) { field.visibilityRules = []; } @@ -121,6 +126,7 @@ export class DescriptionTemplateEditorFieldComponent extends BaseComponent imple fieldType: type } field.data = data; + field.defaultValue = null; break; } case DescriptionTemplateFieldType.RADIO_BOX: { @@ -148,7 +154,15 @@ export class DescriptionTemplateEditorFieldComponent extends BaseComponent imple case DescriptionTemplateFieldType.FREE_TEXT: case DescriptionTemplateFieldType.TEXT_AREA: case DescriptionTemplateFieldType.RICH_TEXT_AREA: - case DescriptionTemplateFieldType.DATE_PICKER: + case DescriptionTemplateFieldType.DATE_PICKER:{ + const data: DescriptionTemplateLabelData = { + label: '', + fieldType: type + } + field.data = data; + + break; + } case DescriptionTemplateFieldType.TAGS: case DescriptionTemplateFieldType.DATASET_IDENTIFIER: case DescriptionTemplateFieldType.VALIDATION: { @@ -157,6 +171,7 @@ export class DescriptionTemplateEditorFieldComponent extends BaseComponent imple fieldType: type } field.data = data; + field.defaultValue = null; break; } @@ -168,6 +183,7 @@ export class DescriptionTemplateEditorFieldComponent extends BaseComponent imple fieldType: type } field.data = data; + field.defaultValue = null; break; } case DescriptionTemplateFieldType.UPLOAD: { @@ -178,6 +194,7 @@ export class DescriptionTemplateEditorFieldComponent extends BaseComponent imple fieldType: type } field.data = data; + field.defaultValue = null; break; } } @@ -248,4 +265,39 @@ export class DescriptionTemplateEditorFieldComponent extends BaseComponent imple onDelete() { this.delete.emit(); } + + + isTextType(type: DescriptionTemplateFieldType){ + return type == DescriptionTemplateFieldType.FREE_TEXT || + type == DescriptionTemplateFieldType.TEXT_AREA || type == DescriptionTemplateFieldType.RICH_TEXT_AREA || + type == DescriptionTemplateFieldType.RADIO_BOX ; + } + + isTextListType(type: DescriptionTemplateFieldType){ + return type == DescriptionTemplateFieldType.TAGS || type == DescriptionTemplateFieldType.INTERNAL_ENTRIES_DMPS || + type == DescriptionTemplateFieldType.INTERNAL_ENTRIES_DESCRIPTIONS || type == DescriptionTemplateFieldType.SELECT; + } + + isDateType(type: DescriptionTemplateFieldType){ + return type == DescriptionTemplateFieldType.DATE_PICKER; + } + + isBooleanType(type: DescriptionTemplateFieldType){ + return type == DescriptionTemplateFieldType.CHECK_BOX || type == DescriptionTemplateFieldType.BOOLEAN_DECISION; + } + + isReferenceType(type: DescriptionTemplateFieldType){ + return type == DescriptionTemplateFieldType.REFERENCE_TYPES; + } + + isExternalIdentifierType(type: DescriptionTemplateFieldType){ + return type == DescriptionTemplateFieldType.VALIDATION || type == DescriptionTemplateFieldType.DATASET_IDENTIFIER; + } + + canSetDefaultValue(type: DescriptionTemplateFieldType){ + return type == DescriptionTemplateFieldType.FREE_TEXT || + type == DescriptionTemplateFieldType.TEXT_AREA || type == DescriptionTemplateFieldType.RICH_TEXT_AREA || + type == DescriptionTemplateFieldType.RADIO_BOX || type == DescriptionTemplateFieldType.SELECT || type == DescriptionTemplateFieldType.DATE_PICKER || + type == DescriptionTemplateFieldType.CHECK_BOX || type == DescriptionTemplateFieldType.BOOLEAN_DECISION; + } } diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/components/visibility-rule/description-template-editor-visibility-rule.component.ts b/dmp-frontend/src/app/ui/admin/description-template/editor/components/visibility-rule/description-template-editor-visibility-rule.component.ts index d813a68f4..9b0cf886c 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/components/visibility-rule/description-template-editor-visibility-rule.component.ts +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/components/visibility-rule/description-template-editor-visibility-rule.component.ts @@ -42,7 +42,7 @@ export class DescriptionTemplateEditorRuleComponent implements OnInit { isTextType(type: DescriptionTemplateFieldType){ return type == DescriptionTemplateFieldType.FREE_TEXT || type == DescriptionTemplateFieldType.TEXT_AREA || type == DescriptionTemplateFieldType.RICH_TEXT_AREA || - type == DescriptionTemplateFieldType.BOOLEAN_DECISION ; + type == DescriptionTemplateFieldType.RADIO_BOX ; } isTextListType(type: DescriptionTemplateFieldType){ @@ -55,7 +55,7 @@ export class DescriptionTemplateEditorRuleComponent implements OnInit { } isBooleanType(type: DescriptionTemplateFieldType){ - return type == DescriptionTemplateFieldType.CHECK_BOX || type == DescriptionTemplateFieldType.RADIO_BOX; + return type == DescriptionTemplateFieldType.CHECK_BOX || type == DescriptionTemplateFieldType.BOOLEAN_DECISION; } isReferenceType(type: DescriptionTemplateFieldType){ diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.model.ts b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.model.ts index 1496c2507..6b2271352 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.model.ts +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.model.ts @@ -5,8 +5,8 @@ import { DescriptionTemplateFieldValidationType } from "@app/core/common/enum/de import { DescriptionTemplateStatus } from "@app/core/common/enum/description-template-status"; import { IsActive } from "@app/core/common/enum/is-active.enum"; import { UserDescriptionTemplateRole } from "@app/core/common/enum/user-description-template-role"; -import { DescriptionTemplate, DescriptionTemplateDefinition, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateLabelData, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateReferenceTypeData, DescriptionTemplateRule, DescriptionTemplateSection, UserDescriptionTemplate } from "@app/core/model/description-template/description-template"; -import { DescriptionTemplateDefinitionPersist, DescriptionTemplateExternalDatasetDataPersist, DescriptionTemplateFieldPersist, DescriptionTemplateFieldSetPersist, DescriptionTemplateLabelAndMultiplicityDataPersist, DescriptionTemplateLabelDataPersist, DescriptionTemplateMultiplicityPersist, DescriptionTemplatePagePersist, DescriptionTemplatePersist, DescriptionTemplateRadioBoxDataPersist, DescriptionTemplateRadioBoxOptionPersist, DescriptionTemplateReferenceTypeFieldPersist, DescriptionTemplateRulePersist, DescriptionTemplateSectionPersist, DescriptionTemplateSelectDataPersist, DescriptionTemplateSelectOptionPersist, DescriptionTemplateUploadDataPersist, DescriptionTemplateUploadOptionPersist, UserDescriptionTemplatePersist } from "@app/core/model/description-template/description-template-persist"; +import { DescriptionTemplate, DescriptionTemplateDefaultValue, DescriptionTemplateDefinition, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateLabelData, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateReferenceTypeData, DescriptionTemplateRule, DescriptionTemplateSection, UserDescriptionTemplate } from "@app/core/model/description-template/description-template"; +import { DescriptionTemplateDefaultValuePersist, DescriptionTemplateDefinitionPersist, DescriptionTemplateExternalDatasetDataPersist, DescriptionTemplateFieldPersist, DescriptionTemplateFieldSetPersist, DescriptionTemplateLabelAndMultiplicityDataPersist, DescriptionTemplateLabelDataPersist, DescriptionTemplateMultiplicityPersist, DescriptionTemplatePagePersist, DescriptionTemplatePersist, DescriptionTemplateRadioBoxDataPersist, DescriptionTemplateRadioBoxOptionPersist, DescriptionTemplateReferenceTypeFieldPersist, DescriptionTemplateRulePersist, DescriptionTemplateSectionPersist, DescriptionTemplateSelectDataPersist, DescriptionTemplateSelectOptionPersist, DescriptionTemplateUploadDataPersist, DescriptionTemplateUploadOptionPersist, UserDescriptionTemplatePersist } from "@app/core/model/description-template/description-template-persist"; import { BaseEditorModel } from "@common/base/base-form-editor-model"; import { BackendErrorValidator } from "@common/forms/validation/custom-validator"; import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; @@ -701,7 +701,7 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF id: string; ordinal: number; schematics: string[]; - defaultValue: string; + defaultValue: DescriptionTemplateDefaultValueEditorModel = new DescriptionTemplateDefaultValueEditorModel(this.validationErrorModel); visibilityRules: DescriptionTemplateRuleEditorModel[] = []; validations: DescriptionTemplateFieldValidationType[] = []; includeInExport: boolean = true; @@ -711,14 +711,15 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF constructor( public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() - ) { } + ) { + } fromModel(item: DescriptionTemplateField | DescriptionTemplateFieldEditorModel): DescriptionTemplateFieldEditorModel { if (item) { this.id = item.id; this.ordinal = item.ordinal; this.schematics = item.schematics; - this.defaultValue = item.defaultValue; + this.defaultValue = new DescriptionTemplateDefaultValueEditorModel(this.validationErrorModel).fromModel(item.defaultValue); this.validations = item.validations; this.includeInExport = item.includeInExport; @@ -745,12 +746,14 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF id: [{ value: this.id, disabled: disabled }, context.getValidation('id').validators], ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal').validators], schematics: [{ value: this.schematics, disabled: disabled }, context.getValidation('schematics').validators], - defaultValue: [{ value: this.defaultValue, disabled: disabled }, context.getValidation('defaultValue').validators], validations: [{ value: this.validations, disabled: disabled }, context.getValidation('validations').validators], includeInExport: [{ value: this.includeInExport, disabled: disabled }, context.getValidation('includeInExport').validators], data: this.data.buildForm({ rootPath: `${rootPath}data.` }), + defaultValue: this.defaultValue.buildForm({ + rootPath: `${rootPath}defaultValue.` + }), visibilityRules: this.formBuilder.array( (this.visibilityRules ?? []).map( (item, index) => item.buildForm({ @@ -865,6 +868,14 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF } } + if (formGroup?.get('defaultValue') != undefined) { + DescriptionTemplateDefaultValueEditorModel.reapplyValidators({ + formGroup: formGroup?.get('defaultValue') as UntypedFormGroup, + rootPath: `${rootPath}defaultValue.`, + validationErrorModel: validationErrorModel + }); + } + (formGroup.get('visibilityRules') as FormArray).controls?.forEach( (control, index) => DescriptionTemplateRuleEditorModel.reapplyValidators({ formGroup: control as UntypedFormGroup, @@ -875,6 +886,87 @@ export class DescriptionTemplateFieldEditorModel implements DescriptionTemplateF } } +export class DescriptionTemplateDefaultValueEditorModel implements DescriptionTemplateDefaultValuePersist { + target: string; + textValue: string; + textListValue: string[]; + dateValue: Date; + booleanValue: boolean; + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + fromModel(item: DescriptionTemplateDefaultValue | DescriptionTemplateDefaultValueEditorModel): DescriptionTemplateDefaultValueEditorModel { + if (item) { + this.textValue = item.textValue; + this.textListValue = item.textListValue; + this.dateValue = item.dateValue; + this.booleanValue = item.booleanValue; + } + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = DescriptionTemplateDefaultValueEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + textValue: [{ value: this.textValue, disabled: disabled }, context.getValidation('textValue').validators], + textListValue: [{ value: this.textListValue, disabled: disabled }, context.getValidation('textListValue').validators], + dateValue: [{ value: this.dateValue, disabled: disabled }, context.getValidation('dateValue').validators], + booleanValue: [{ value: this.booleanValue, disabled: disabled }, context.getValidation('booleanValue').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: 'textValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}textValue`)] }); + baseValidationArray.push({ key: 'textListValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}textListValue`)] }); + baseValidationArray.push({ key: 'dateValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}dateValue`)] }); + baseValidationArray.push({ key: 'booleanValue', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}booleanValue`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } + + static reapplyValidators(params: { + formGroup: UntypedFormGroup, + validationErrorModel: ValidationErrorModel, + rootPath: string + }): void { + + const { formGroup, rootPath, validationErrorModel } = params; + const context = DescriptionTemplateDefaultValueEditorModel.createValidationContext({ + rootPath, + validationErrorModel + }); + + ['target', 'textValue', 'textListValue', 'dateValue', 'booleanValue'].forEach(keyField => { + const control = formGroup?.get(keyField); + control?.clearValidators(); + control?.addValidators(context.getValidation(keyField).validators); + }) + } +} + export class DescriptionTemplateRuleEditorModel implements DescriptionTemplateRulePersist { target: string; textValue: string; diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.resolver.ts b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.resolver.ts index e5b359826..67be5b0a3 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.resolver.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; -import { DescriptionTemplate, DescriptionTemplateBaseFieldData, DescriptionTemplateDefinition, DescriptionTemplateExternalDatasetData, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateLabelAndMultiplicityData, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateReferenceTypeData, DescriptionTemplateRule, DescriptionTemplateSection, DescriptionTemplateSelectData, DescriptionTemplateSelectOption, DescriptionTemplateUploadData, DescriptionTemplateUploadOption, UserDescriptionTemplate } from '@app/core/model/description-template/description-template'; +import { DescriptionTemplate, DescriptionTemplateBaseFieldData, DescriptionTemplateDefaultValue, DescriptionTemplateDefinition, DescriptionTemplateExternalDatasetData, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateLabelAndMultiplicityData, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateReferenceTypeData, DescriptionTemplateRule, DescriptionTemplateSection, DescriptionTemplateSelectData, DescriptionTemplateSelectOption, DescriptionTemplateUploadData, DescriptionTemplateUploadOption, UserDescriptionTemplate } from '@app/core/model/description-template/description-template'; import { ReferenceType } from '@app/core/model/reference-type/reference-type'; import { Reference } from '@app/core/model/reference/reference'; import { User } from '@app/core/model/user/user'; @@ -61,7 +61,10 @@ export class DescriptionTemplateEditorResolver extends BaseEditorResolver { [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.ordinal)].join('.'), [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.numbering)].join('.'), [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.schematics)].join('.'), - [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.defaultValue)].join('.'), + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.defaultValue), nameof(x => x.textValue)].join('.'), + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.defaultValue), nameof(x => x.textListValue)].join('.'), + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.defaultValue), nameof(x => x.dateValue)].join('.'), + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.defaultValue), nameof(x => x.booleanValue)].join('.'), // [nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.fieldType)].join('.'), [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.includeInExport)].join('.'), [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.validations)].join('.'), diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts index 8d16700eb..0852d8cef 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.model.ts @@ -220,10 +220,10 @@ export class DescriptionPropertyDefinitionEditorModel implements DescriptionProp const fields = new Map(); definitionFieldSet.fields.forEach(definitionField => { fields.set(definitionField.id, { - textValue: undefined, - textListValue: undefined, - dateValue: undefined, - booleanValue: definitionField.defaultValue && definitionField.defaultValue.length > 0 ? definitionField.defaultValue.trim().toLocaleLowerCase() == "true" : false, //TODO: booleanValue default value + textValue: definitionField.defaultValue ? definitionField.defaultValue.textValue : undefined, + textListValue: definitionField.defaultValue ? definitionField.defaultValue.textListValue : undefined, + dateValue: definitionField.defaultValue ? definitionField.defaultValue.dateValue : undefined, + booleanValue: definitionField.defaultValue ? definitionField.defaultValue.booleanValue : undefined, externalIdentifier: undefined, references: undefined }); diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts index 98c01a07a..482b8f5c1 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { DescriptionStatus } from '@app/core/common/enum/description-status'; import { AppPermission } from '@app/core/common/enum/permission.enum'; -import { DescriptionTemplate, DescriptionTemplateBaseFieldData, DescriptionTemplateDefinition, DescriptionTemplateExternalDatasetData, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateReferenceTypeData, DescriptionTemplateRule, DescriptionTemplateSection, DescriptionTemplateSelectData, DescriptionTemplateSelectOption, DescriptionTemplateUploadData, DescriptionTemplateUploadOption } from '@app/core/model/description-template/description-template'; +import { DescriptionTemplate, DescriptionTemplateBaseFieldData, DescriptionTemplateDefaultValue, DescriptionTemplateDefinition, DescriptionTemplateExternalDatasetData, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateReferenceTypeData, DescriptionTemplateRule, DescriptionTemplateSection, DescriptionTemplateSelectData, DescriptionTemplateSelectOption, DescriptionTemplateUploadData, DescriptionTemplateUploadOption } from '@app/core/model/description-template/description-template'; import { Description, DescriptionExternalIdentifier, DescriptionField, DescriptionPropertyDefinition, DescriptionPropertyDefinitionFieldSet, DescriptionPropertyDefinitionFieldSetItem, DescriptionReference, DescriptionReferenceData, DescriptionTag } from '@app/core/model/description/description'; import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { Dmp, DmpDescriptionTemplate } from '@app/core/model/dmp/dmp'; @@ -96,51 +96,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver { public static descriptionTemplateLookupFields(prefix?: string): string[] { return [ - (prefix ? prefix + '.' : '') + [nameof(x => x.id)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.label)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.version)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.versionStatus)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.groupId)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.isActive)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.id)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.ordinal)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.title)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.id)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.ordinal)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.title)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.description)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.sections)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.id)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.ordinal)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.title)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.description)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.extendedDescription)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.additionalInformation)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.hasCommentField)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.hasMultiplicity)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.multiplicity), nameof(x => x.min)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.multiplicity), nameof(x => x.max)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.multiplicity), nameof(x => x.placeholder)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.multiplicity), nameof(x => x.tableView)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.id)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.defaultValue)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.validations)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.visibilityRules), nameof(x => x.target)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.visibilityRules), nameof(x => x.textValue)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.visibilityRules), nameof(x => x.textListValue)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.visibilityRules), nameof(x => x.dateValue)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.visibilityRules), nameof(x => x.booleanValue)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.label)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.fieldType)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.options), nameof(x => x.label)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.options), nameof(x => x.value)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.multipleSelect)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.type)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.maxFileSizeInMB)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.types), nameof(x => x.label)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.types), nameof(x => x.value)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.referenceType), nameof(x => x.id)].join('.'), - (prefix ? prefix + '.' : '') + [nameof(x => x.definition), nameof(x => x.pages), nameof(x => x.sections), nameof(x => x.fieldSets), nameof(x => x.fields), nameof(x => x.data), nameof(x => x.referenceType), nameof(x => x.name)].join('.'), + "DescriptionEditorDescriptionTemplateLookupFields" ] } diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html index 00ce8250c..22f37d0d3 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field/form-field.component.html @@ -7,6 +7,7 @@
{{fieldSet.extendedDescription}}
+ {{propertiesFormGroup?.get(field.id).value | json}} {{propertiesFormGroup?.get(field.id).get('textValue').getError('backendError').message}} diff --git a/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DescriptionTemplateXmlMigrationService.java b/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DescriptionTemplateXmlMigrationService.java index 0d68d0e77..33fb59fb8 100644 --- a/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DescriptionTemplateXmlMigrationService.java +++ b/dmp-migration-tool/web/src/main/java/eu/old/eudat/migration/DescriptionTemplateXmlMigrationService.java @@ -1,6 +1,7 @@ package eu.old.eudat.migration; import com.fasterxml.jackson.annotation.JsonValue; +import eu.old.eudat.models.data.components.commons.DefaultValue; import org.opencdmp.commons.XmlHandlingService; import org.opencdmp.commons.enums.*; import org.opencdmp.commons.types.descriptiontemplate.*; @@ -199,7 +200,6 @@ public class DescriptionTemplateXmlMigrationService { data.setOrdinal(persist.getOrdinal()); data.setSchematics(persist.getSchematics()); data.setNumbering(persist.getNumbering()); - if (persist.getDefaultValue() != null) data.setDefaultValue(persist.getDefaultValue().getValue()); if (persist.getValidations() != null) data.setValidations(persist.getValidations().stream().map(x-> { switch (x){ case NONE -> { @@ -233,7 +233,8 @@ public class DescriptionTemplateXmlMigrationService { } } } - + + if (persist.getDefaultValue() != null) data.setDefaultValue(this.buildDefaultValueEntity(persist.getDefaultValue(), data.getData().getFieldType())); if (persist.getVisible() != null && !this.conventionService.isListNullOrEmpty(persist.getVisible().getRules())) { data.setVisibilityRules(new ArrayList<>()); for (Rule fieldPersist : persist.getVisible().getRules()) { @@ -404,6 +405,51 @@ public class DescriptionTemplateXmlMigrationService { data.setReferenceTypeId(referenceTypeId); return data; } + + private @NotNull DefaultValueEntity buildDefaultValueEntity(DefaultValue persist, FieldType fieldType) { + DefaultValueEntity data = new DefaultValueEntity(); + if (persist == null) + return data; + String textValue = persist.getValue(); + if (textValue == null || textValue.isEmpty()) return data; + + switch (fieldType){ + case FREE_TEXT, TEXT_AREA, RICH_TEXT_AREA, RADIO_BOX -> data.setTextValue(textValue.trim()); + case CHECK_BOX, BOOLEAN_DECISION -> { + if (!this.conventionService.isNullOrEmpty(textValue)) { + data.setBooleanValue("true".equals(textValue.trim().toLowerCase(Locale.ROOT))); + } + } + case DATE_PICKER -> { + Instant instant = null; + if(!this.conventionService.isNullOrEmpty(textValue)) { + try { + instant = Instant.parse(textValue); + } catch (DateTimeParseException ex) { + instant = LocalDate.parse(textValue).atStartOfDay().toInstant(ZoneOffset.UTC); + } + } + data.setDateValue(instant); + } + case SELECT -> { + if(!this.conventionService.isNullOrEmpty(textValue)) { + String[] valuesParsed = migrationTools.tryParseJsonAsObjectString(String[].class, textValue); + data.setTextListValue(valuesParsed == null ? List.of(textValue) : Arrays.stream(valuesParsed).toList()); + } + } + case DATASET_IDENTIFIER, VALIDATION -> { + throw new NotSupportedException("Upload validator not supported"); + } + case UPLOAD -> throw new NotSupportedException("Upload validator not supported"); + case TAGS -> throw new NotSupportedException("Tags validator not supported"); + + case INTERNAL_ENTRIES_DMPS -> throw new NotSupportedException("INTERNAL_ENTRIES_DMPS validator not supported"); + case INTERNAL_ENTRIES_DESCRIPTIONS -> throw new NotSupportedException("INTERNAL_ENTRIES_DESCRIPTIONS validator not supported"); + case REFERENCE_TYPES -> throw new NotSupportedException("REFERENCE_TYPES validator not supported"); + default -> throw new MyApplicationException("unrecognized type " + fieldType); + } + return data; + } private @NotNull RuleEntity buildRuleEntity(Rule persist, FieldType fieldType) {