diff --git a/dmp-backend/core/pom.xml b/dmp-backend/core/pom.xml index e12019146..d176c6f75 100644 --- a/dmp-backend/core/pom.xml +++ b/dmp-backend/core/pom.xml @@ -50,7 +50,7 @@ gr.cite.opendmp common-models - 0.0.3 + 0.0.4 gr.cite.opendmp diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/ExternalIdentifierEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/ExternalIdentifierEntity.java new file mode 100644 index 000000000..101fbc5ff --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/ExternalIdentifierEntity.java @@ -0,0 +1,32 @@ +package eu.eudat.commons.types.descriptiontemplate; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; + +@XmlAccessorType(XmlAccessType.FIELD) +public class ExternalIdentifierEntity { + + @XmlAttribute(name="identifier") + private String identifier; + + @XmlAttribute(name="type") + private String type; + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/RuleEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/RuleEntity.java index 6551cfbbb..0368b7b65 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/RuleEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/RuleEntity.java @@ -1,15 +1,25 @@ package eu.eudat.commons.types.descriptiontemplate; -import jakarta.xml.bind.annotation.XmlAccessType; -import jakarta.xml.bind.annotation.XmlAccessorType; -import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.*; + +import java.time.Instant; +import java.util.List; @XmlAccessorType(XmlAccessType.FIELD) public class RuleEntity { @XmlAttribute(name="target") private String target; @XmlAttribute(name="value") - private String value; + private String textValue; + + @XmlElementWrapper(name = "textListValues") + @XmlElement(name = "textListValue") + private List textListValue; + + @XmlElement(name = "dateValue") + private Instant dateValue; + @XmlElement(name="externalIdentifier") + private ExternalIdentifierEntity externalIdentifier; public String getTarget() { return target; @@ -19,12 +29,36 @@ public class RuleEntity { this.target = target; } - public String getValue() { - return value; + public String getTextValue() { + return textValue; } - public void setValue(String value) { - this.value = value; + public void setTextValue(String textValue) { + this.textValue = textValue; } + public List getTextListValue() { + return textListValue; + } + + public void setTextListValue(List textListValue) { + this.textListValue = textListValue; + } + + public Instant getDateValue() { + return dateValue; + } + + public void setDateValue(Instant dateValue) { + this.dateValue = dateValue; + } + + public ExternalIdentifierEntity getExternalIdentifier() { + return externalIdentifier; + } + + public void setExternalIdentifier(ExternalIdentifierEntity externalIdentifier) { + this.externalIdentifier = externalIdentifier; + } } + diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/importexport/ExternalIdentifierImportExport.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/importexport/ExternalIdentifierImportExport.java new file mode 100644 index 000000000..863c9834d --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/importexport/ExternalIdentifierImportExport.java @@ -0,0 +1,32 @@ +package eu.eudat.commons.types.descriptiontemplate.importexport; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; + +@XmlAccessorType(XmlAccessType.FIELD) +public class ExternalIdentifierImportExport { + + @XmlAttribute(name="identifier") + private String identifier; + + @XmlAttribute(name="type") + private String type; + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/importexport/RuleImportExport.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/importexport/RuleImportExport.java index 8b39e2754..480a48f83 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/importexport/RuleImportExport.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/descriptiontemplate/importexport/RuleImportExport.java @@ -1,15 +1,26 @@ package eu.eudat.commons.types.descriptiontemplate.importexport; -import eu.eudat.model.persist.descriptiontemplatedefinition.RulePersist; import jakarta.xml.bind.annotation.*; +import java.time.Instant; +import java.util.List; + @XmlAccessorType(XmlAccessType.FIELD) public class RuleImportExport { @XmlAttribute(name="target") private String target; @XmlAttribute(name="value") - private String value; + private String textValue; + + @XmlElementWrapper(name = "textListValues") + @XmlElement(name = "textListValue") + private List textListValue; + @XmlElement(name = "dateValue") + private Instant dateValue; + + @XmlElement(name="externalIdentifier") + private ExternalIdentifierImportExport externalIdentifier; public String getTarget() { return target; @@ -19,11 +30,35 @@ public class RuleImportExport { this.target = target; } - public String getValue() { - return value; + public String getTextValue() { + return textValue; } - public void setValue(String value) { - this.value = value; + public void setTextValue(String textValue) { + this.textValue = textValue; + } + + public List getTextListValue() { + return textListValue; + } + + public void setTextListValue(List textListValue) { + this.textListValue = textListValue; + } + + public Instant getDateValue() { + return dateValue; + } + + public void setDateValue(Instant dateValue) { + this.dateValue = dateValue; + } + + public ExternalIdentifierImportExport getExternalIdentifier() { + return externalIdentifier; + } + + public void setExternalIdentifier(ExternalIdentifierImportExport externalIdentifier) { + this.externalIdentifier = externalIdentifier; } } \ No newline at end of file diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/description/DescriptionCommonModelBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/description/DescriptionCommonModelBuilder.java index 39274feca..d723833f4 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/description/DescriptionCommonModelBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/description/DescriptionCommonModelBuilder.java @@ -21,6 +21,7 @@ import eu.eudat.model.builder.commonmodels.CommonModelBuilderItemResponse; import eu.eudat.model.builder.commonmodels.dmp.DmpCommonModelBuilder; import eu.eudat.model.builder.commonmodels.descriptiontemplate.DescriptionTemplateCommonModelBuilder; import eu.eudat.query.*; +import eu.eudat.service.visibility.VisibilityServiceImpl; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyApplicationException; @@ -103,6 +104,7 @@ public class DescriptionCommonModelBuilder extends BaseCommonModelBuilder(m, d)); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/descriptiontemplate/FieldCommonModelBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/descriptiontemplate/FieldCommonModelBuilder.java index 6b6aafe9f..452788f11 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/descriptiontemplate/FieldCommonModelBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/descriptiontemplate/FieldCommonModelBuilder.java @@ -71,7 +71,6 @@ public class FieldCommonModelBuilder extends BaseCommonModelBuilder { - private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); - @Autowired - public RuleCommonModelBuilder( - ConventionService conventionService - ) { - super(conventionService, new LoggerService(LoggerFactory.getLogger(RuleCommonModelBuilder.class))); - } - - public RuleCommonModelBuilder authorize(EnumSet values) { - this.authorize = values; - return this; - } - - @Override - protected List> buildInternal(List data) throws MyApplicationException { - this.logger.debug("building for {}", Optional.ofNullable(data).map(List::size).orElse(0)); - if (data == null || data.isEmpty()) return new ArrayList<>(); - - List> models = new ArrayList<>(); - for (RuleEntity d : data) { - RuleModel m = new RuleModel(); - m.setTarget(d.getTarget()); - m.setValue(d.getValue()); - models.add(new CommonModelBuilderItemResponse<>(m, d)); - } - - this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); - - return models; - } -} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptionpropertiesdefinition/FieldBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptionpropertiesdefinition/FieldBuilder.java index 2b7a5e99e..e2fbf1ec9 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptionpropertiesdefinition/FieldBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptionpropertiesdefinition/FieldBuilder.java @@ -4,16 +4,11 @@ import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.commons.enums.FieldType; import eu.eudat.commons.types.description.FieldEntity; import eu.eudat.convention.ConventionService; -import eu.eudat.data.DescriptionReferenceEntity; -import eu.eudat.model.DescriptionReference; import eu.eudat.model.Reference; import eu.eudat.model.builder.BaseBuilder; import eu.eudat.model.builder.ReferenceBuilder; import eu.eudat.model.descriptionproperties.Field; -import eu.eudat.model.descriptionproperties.PropertyDefinition; -import eu.eudat.model.persist.descriptionproperties.FieldPersist; import eu.eudat.query.ReferenceQuery; -import eu.eudat.service.fielddatahelper.FieldDataHelperServiceProvider; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyApplicationException; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptiontemplatedefinition/ExternalIdentifierBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptiontemplatedefinition/ExternalIdentifierBuilder.java new file mode 100644 index 000000000..493370ce5 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptiontemplatedefinition/ExternalIdentifierBuilder.java @@ -0,0 +1,58 @@ +package eu.eudat.model.builder.descriptiontemplatedefinition; + +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.types.descriptiontemplate.ExternalIdentifierEntity; +import eu.eudat.convention.ConventionService; +import eu.eudat.model.builder.BaseBuilder; +import eu.eudat.model.descriptiontemplatedefinition.ExternalIdentifier; +import eu.eudat.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.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("descriptiontemplatedefinition.ExternalIdentifierBuilder") +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class ExternalIdentifierBuilder extends BaseBuilder { + + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + @Autowired + public ExternalIdentifierBuilder( + ConventionService conventionService, BuilderFactory builderFactory, FieldDataHelperServiceProvider fieldDataHelperServiceProvider) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(ExternalIdentifierBuilder.class))); + } + + public ExternalIdentifierBuilder authorize(EnumSet values) { + this.authorize = values; + return this; + } + + @Override + public List build(FieldSet fields, List data) throws MyApplicationException { + this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0)); + this.logger.trace(new DataLogEntry("requested fields", fields)); + if (fields == null || data == null || fields.isEmpty()) + return new ArrayList<>(); + + + List models = new ArrayList<>(); + for (ExternalIdentifierEntity d : data) { + ExternalIdentifier m = new ExternalIdentifier(); + if (fields.hasField(this.asIndexer(ExternalIdentifier._identifier))) m.setIdentifier(d.getIdentifier()); + if (fields.hasField(this.asIndexer(ExternalIdentifier._type))) m.setType(d.getType()); + + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptiontemplatedefinition/FieldBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptiontemplatedefinition/FieldBuilder.java index e4da9b38e..3f2fb180f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptiontemplatedefinition/FieldBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptiontemplatedefinition/FieldBuilder.java @@ -63,7 +63,7 @@ public class FieldBuilder extends BaseBuilder { 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 (!visibilityRulesFields.isEmpty() && d.getVisibilityRules() != null) m.setVisibilityRules(this.builderFactory.builder(RuleBuilder.class).authorize(this.authorize).build(visibilityRulesFields, d.getVisibilityRules())); + 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()); m.setData(fieldDataHelperService.buildOne(dataFields, d.getData(), this.authorize)); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptiontemplatedefinition/RuleBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptiontemplatedefinition/RuleBuilder.java index 4b226eb3f..9b05dedf0 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptiontemplatedefinition/RuleBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/descriptiontemplatedefinition/RuleBuilder.java @@ -1,11 +1,18 @@ package eu.eudat.model.builder.descriptiontemplatedefinition; import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.enums.FieldType; import eu.eudat.commons.types.descriptiontemplate.RuleEntity; import eu.eudat.convention.ConventionService; +import eu.eudat.model.Reference; import eu.eudat.model.builder.BaseBuilder; +import eu.eudat.model.builder.ReferenceBuilder; import eu.eudat.model.descriptiontemplatedefinition.Rule; +import eu.eudat.query.ReferenceQuery; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.DataLogEntry; import gr.cite.tools.logging.LoggerService; @@ -16,17 +23,24 @@ import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import java.util.*; +import java.util.stream.Collectors; @Component @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class RuleBuilder extends BaseBuilder { + private final BuilderFactory builderFactory; + private final QueryFactory queryFactory; private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + private eu.eudat.commons.types.descriptiontemplate.FieldEntity fieldEntity; + @Autowired public RuleBuilder( - ConventionService conventionService) { + ConventionService conventionService, BuilderFactory builderFactory, QueryFactory queryFactory) { super(conventionService, new LoggerService(LoggerFactory.getLogger(RuleBuilder.class))); + this.builderFactory = builderFactory; + this.queryFactory = queryFactory; } public RuleBuilder authorize(EnumSet values) { @@ -34,21 +48,70 @@ public class RuleBuilder extends BaseBuilder { return this; } + public RuleBuilder withFieldEntity(eu.eudat.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; + + FieldSet externalIdentifierFields = fields.extractPrefixed(this.asPrefix(Rule._externalIdentifier)); + FieldSet referenceFields = fields.extractPrefixed(this.asPrefix(Rule._references)); + Map referenceItemsMap = FieldType.isReferenceType(fieldType) ? this.collectReferences(referenceFields, data) : null; List models = new ArrayList<>(); for (RuleEntity d : data) { Rule m = new Rule(); - if (fields.hasField(this.asIndexer(Rule._target))) m.setTarget(d.getTarget()); - if (fields.hasField(this.asIndexer(Rule._value))) m.setValue(d.getValue()); + if (fields.hasField(this.asIndexer(Rule._dateValue)) && FieldType.isDateType(fieldType)) m.setDateValue(d.getDateValue()); + if (fields.hasField(this.asIndexer(Rule._textValue)) && FieldType.isTextType(fieldType)) m.setTextValue(d.getTextValue()); + if (fields.hasField(this.asIndexer(Rule._textListValue)) && FieldType.isTextListType(fieldType)) m.setTextListValue(d.getTextListValue()); + if (!referenceFields.isEmpty() && FieldType.isReferenceType(fieldType) && referenceItemsMap != null && d.getTextListValue() != null && !d.getTextListValue().isEmpty()) { + m.setReferences(new ArrayList<>()); + for (UUID referenceId : d.getTextListValue().stream().map(UUID::fromString).toList()){ + if (referenceItemsMap.containsKey(referenceId)) m.getReferences().add(referenceItemsMap.get(referenceId)); + } + } + if (!externalIdentifierFields.isEmpty() && d.getExternalIdentifier() != null && FieldType.isExternalIdentifierType(fieldType)) m.setExternalIdentifier(this.builderFactory.builder(ExternalIdentifierBuilder.class).authorize(this.authorize).build(externalIdentifierFields, d.getExternalIdentifier())); + models.add(m); } this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); return models; } + + private Map collectReferences(FieldSet fields, List data) throws MyApplicationException { + if (fields.isEmpty() || data.isEmpty()) + return null; + this.logger.debug("checking related - {}", Reference.class.getSimpleName()); + + Map itemMap; + if (!fields.hasOtherField(this.asIndexer(Reference._id))) { + itemMap = this.asEmpty( + data.stream().map(RuleEntity::getTextListValue).flatMap(List::stream).map(UUID::fromString).distinct().collect(Collectors.toList()), + x -> { + Reference item = new Reference(); + item.setId(x); + return item; + }, + Reference::getId); + } else { + FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(Reference._id); + ReferenceQuery q = this.queryFactory.query(ReferenceQuery.class).authorize(this.authorize).ids(data.stream().map(RuleEntity::getTextListValue).flatMap(List::stream).map(UUID::fromString).distinct().collect(Collectors.toList())); + itemMap = this.builderFactory.builder(ReferenceBuilder.class).authorize(this.authorize).asForeignKey(q, clone, Reference::getId); + } + if (!fields.hasField(Reference._id)) { + itemMap.forEach((id, item) -> { + if (item != null) + item.setId(null); + }); + } + + return itemMap; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/descriptiontemplatedefinition/ExternalIdentifier.java b/dmp-backend/core/src/main/java/eu/eudat/model/descriptiontemplatedefinition/ExternalIdentifier.java new file mode 100644 index 000000000..7bf9639b8 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/descriptiontemplatedefinition/ExternalIdentifier.java @@ -0,0 +1,27 @@ +package eu.eudat.model.descriptiontemplatedefinition; + +public class ExternalIdentifier { + + private String identifier; + public static final String _identifier = "identifier"; + + private String type; + public static final String _type = "type"; + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/descriptiontemplatedefinition/Rule.java b/dmp-backend/core/src/main/java/eu/eudat/model/descriptiontemplatedefinition/Rule.java index 9d8d401c4..8723070f5 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/descriptiontemplatedefinition/Rule.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/descriptiontemplatedefinition/Rule.java @@ -1,13 +1,30 @@ package eu.eudat.model.descriptiontemplatedefinition; +import eu.eudat.model.Reference; + +import java.time.Instant; +import java.util.List; + public class Rule { public final static String _target = "target"; private String target; - public final static String _value = "value"; - private String value; + 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 List references; + public static final String _references = "references"; + + private ExternalIdentifier externalIdentifier; + public static final String _externalIdentifier = "externalIdentifier"; public String getTarget() { @@ -18,12 +35,43 @@ public class Rule { this.target = target; } - public String getValue() { - return value; + public String getTextValue() { + return textValue; } - public void setValue(String value) { - this.value = value; + public void setTextValue(String textValue) { + this.textValue = textValue; } + public List getTextListValue() { + return textListValue; + } + + public void setTextListValue(List textListValue) { + this.textListValue = textListValue; + } + + public Instant getDateValue() { + return dateValue; + } + + public void setDateValue(Instant dateValue) { + this.dateValue = dateValue; + } + + public List getReferences() { + return references; + } + + public void setReferences(List references) { + this.references = references; + } + + public ExternalIdentifier getExternalIdentifier() { + return externalIdentifier; + } + + public void setExternalIdentifier(ExternalIdentifier externalIdentifier) { + this.externalIdentifier = externalIdentifier; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DescriptionFieldToDatasetFieldMapper.java b/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DescriptionFieldToDatasetFieldMapper.java index 0c784c516..00482c0ee 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DescriptionFieldToDatasetFieldMapper.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/mapper/publicapi/DescriptionFieldToDatasetFieldMapper.java @@ -1,5 +1,6 @@ package eu.eudat.model.mapper.publicapi; +import eu.eudat.commons.types.descriptiontemplate.ExternalIdentifierEntity; import eu.eudat.commons.types.descriptiontemplate.RuleEntity; import eu.eudat.model.publicapi.datasetwizard.DefaultValueEntity; import eu.eudat.model.publicapi.datasetwizard.FieldDescriptionEntity; @@ -27,7 +28,14 @@ public class DescriptionFieldToDatasetFieldMapper { VisibilityEntity visibilityEntity = new VisibilityEntity(); visibilityEntity.setRules(field.getVisibilityRules().stream().map(x -> { RuleEntity ruleEntity = new RuleEntity(); - ruleEntity.setValue(x.getValue()); + ruleEntity.setDateValue(x.getDateValue()); + ruleEntity.setTextValue(x.getTextValue()); + ruleEntity.setTextListValue(x.getTextListValue()); + if (x.getExternalIdentifier() != null){ + ruleEntity.setExternalIdentifier(new ExternalIdentifierEntity()); + ruleEntity.getExternalIdentifier().setIdentifier(x.getExternalIdentifier().getIdentifier()); + ruleEntity.getExternalIdentifier().setType(x.getExternalIdentifier().getType()); + } ruleEntity.setTarget(x.getTarget()); return ruleEntity; }).toList()); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/ExternalIdentifierPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/ExternalIdentifierPersist.java new file mode 100644 index 000000000..33ef22fef --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/ExternalIdentifierPersist.java @@ -0,0 +1,68 @@ +package eu.eudat.model.persist.descriptiontemplatedefinition; + +import eu.eudat.commons.validation.BaseValidator; +import eu.eudat.convention.ConventionService; +import eu.eudat.errorcode.ErrorThesaurusProperties; +import gr.cite.tools.validation.specification.Specification; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +public class ExternalIdentifierPersist { + + private String identifier; + public static final String _identifier = "identifier"; + + private String type; + public static final String _type = "type"; + + public String getIdentifier() { + return identifier; + } + + public void setIdentifier(String identifier) { + this.identifier = identifier; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Component(PersistValidator.ValidatorName) + public static class PersistValidator extends BaseValidator { + + public static final String ValidatorName = "descriptiontemplatedefinition.ExternalIdentifierPersistPersistValidator"; + + private final MessageSource messageSource; + + protected PersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) { + super(conventionService, errors); + this.messageSource = messageSource; + } + + @Override + protected Class modelClass() { + return ExternalIdentifierPersist.class; + } + + @Override + protected List specifications(ExternalIdentifierPersist item) { + return Arrays.asList( + this.spec() + .must(() -> !this.isEmpty(item.getIdentifier())) + .failOn(ExternalIdentifierPersist._identifier).failWith(messageSource.getMessage("Validation_Required", new Object[]{ExternalIdentifierPersist._identifier}, LocaleContextHolder.getLocale())), + this.spec() + .must(() -> !this.isEmpty(item.getType())) + .failOn(ExternalIdentifierPersist._type).failWith(messageSource.getMessage("Validation_Required", new Object[]{ExternalIdentifierPersist._type}, LocaleContextHolder.getLocale())) + ); + } + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/FieldPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/FieldPersist.java index e93482197..17f242c98 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/FieldPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/FieldPersist.java @@ -149,7 +149,7 @@ public class FieldPersist { .iff(() -> !this.isListNullOrEmpty(item.getVisibilityRules())) .on(FieldPersist._visibilityRules) .over(item.getVisibilityRules()) - .using((itm) -> this.validatorFactory.validator(RulePersist.RulePersistValidator.class)), + .using((itm) -> this.validatorFactory.validator(RulePersist.RulePersistValidator.class).withFieldPersist(item)), this.refSpec() .iff(() -> !this.isNull(item.getData()) && item.getData().getFieldType() != null) .on(FieldPersist._data) diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/RulePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/RulePersist.java index c454eca86..f5aaf09e9 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/RulePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/descriptiontemplatedefinition/RulePersist.java @@ -1,6 +1,10 @@ package eu.eudat.model.persist.descriptiontemplatedefinition; +import eu.eudat.commons.enums.FieldType; import eu.eudat.commons.validation.BaseValidator; +import eu.eudat.model.persist.ReferencePersist; +import eu.eudat.model.persist.descriptionproperties.FieldPersist; +import gr.cite.tools.validation.ValidatorFactory; import gr.cite.tools.validation.specification.Specification; import eu.eudat.convention.ConventionService; import eu.eudat.errorcode.ErrorThesaurusProperties; @@ -10,6 +14,7 @@ import org.springframework.context.annotation.Scope; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Component; +import java.time.Instant; import java.util.Arrays; import java.util.List; @@ -19,9 +24,21 @@ public class RulePersist { public static final String _target = "target"; - private String value = null; + private String textValue; + public static final String _textValue = "textValue"; - public static final String _value = "value"; + private List textListValue; + public static final String _textListValue = "textListValue"; + + private Instant dateValue; + public static final String _dateValue = "dateValue"; + + private List references; + public static final String _references = "references"; + + + private ExternalIdentifierPersist externalIdentifier; + public static final String _externalIdentifier = "externalIdentifier"; public String getTarget() { return target; @@ -31,12 +48,44 @@ public class RulePersist { this.target = target; } - public String getValue() { - return value; + public String getTextValue() { + return textValue; } - public void setValue(String value) { - this.value = value; + public void setTextValue(String textValue) { + this.textValue = textValue; + } + + public List getTextListValue() { + return textListValue; + } + + public void setTextListValue(List textListValue) { + this.textListValue = textListValue; + } + + public Instant getDateValue() { + return dateValue; + } + + public void setDateValue(Instant dateValue) { + this.dateValue = dateValue; + } + + public List getReferences() { + return references; + } + + public void setReferences(List references) { + this.references = references; + } + + public ExternalIdentifierPersist getExternalIdentifier() { + return externalIdentifier; + } + + public void setExternalIdentifier(ExternalIdentifierPersist externalIdentifier) { + this.externalIdentifier = externalIdentifier; } @Component(RulePersistValidator.ValidatorName) @@ -46,10 +95,18 @@ public class RulePersist { public static final String ValidatorName = "DescriptionTemplate.RulePersistValidator"; private final MessageSource messageSource; + private final ValidatorFactory validatorFactory; + private eu.eudat.model.persist.descriptiontemplatedefinition.FieldPersist fieldEntity; - protected RulePersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) { + protected RulePersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { super(conventionService, errors); this.messageSource = messageSource; + this.validatorFactory = validatorFactory; + } + + public RulePersistValidator withFieldPersist(eu.eudat.model.persist.descriptiontemplatedefinition.FieldPersist fieldEntity) { + this.fieldEntity = fieldEntity; + return this; } @Override @@ -59,13 +116,53 @@ public class RulePersist { @Override protected List specifications(RulePersist item) { + FieldType fieldType = this.fieldEntity != null && this.fieldEntity.getData() != null ? this.fieldEntity.getData().getFieldType() : FieldType.FREE_TEXT; return Arrays.asList( this.spec() .must(() -> !this.isEmpty(item.getTarget())) .failOn(RulePersist._target).failWith(messageSource.getMessage("Validation_Required", new Object[]{RulePersist._target}, LocaleContextHolder.getLocale())), this.spec() - .must(() -> !this.isEmpty(item.getValue())) - .failOn(RulePersist._value).failWith(messageSource.getMessage("Validation_Required", new Object[]{RulePersist._value}, LocaleContextHolder.getLocale())) + .iff(()-> FieldType.isTextType(fieldType)) + .must(() -> !this.isEmpty(item.getTextValue())) + .failOn(FieldPersist._textValue).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._textValue}, LocaleContextHolder.getLocale())), + this.spec() + .iff(()-> FieldType.isDateType(fieldType)) + .must(() -> !this.isNull(item.getDateValue())) + .failOn(FieldPersist._dateValue).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._dateValue}, LocaleContextHolder.getLocale())), + this.spec() + .iff(()-> FieldType.isExternalIdentifierType(fieldType)) + .must(() -> !this.isNull(item.getExternalIdentifier())) + .failOn(FieldPersist._externalIdentifier).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._externalIdentifier}, LocaleContextHolder.getLocale())), + this.spec() + .iff(()-> FieldType.isTextListType(fieldType)) + .must(() -> !this.isNull(item.getTextListValue())) + .failOn(FieldPersist._textListValue).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._textListValue}, LocaleContextHolder.getLocale())), + this.spec() + .iff(()-> FieldType.isReferenceType(fieldType)) + .must(() -> !this.isNull(item.getTextListValue())) + .failOn(FieldPersist._textListValue).failWith(messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._textListValue}, LocaleContextHolder.getLocale())), + this.spec() + .iff(()-> !this.isEmpty(item.getTextValue()) && fieldType.equals(FieldType.CHECK_BOX) || fieldType.equals(FieldType.BOOLEAN_DECISION) ) + .must(() -> this.isBoolean(item.getTextValue())) + .failOn(FieldPersist._textValue).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{FieldPersist._textValue}, LocaleContextHolder.getLocale())), + this.spec() + .iff(()-> !this.isEmpty(item.getTextValue()) && fieldType.equals(FieldType.CURRENCY)) + .must(() -> this.isUUID(item.getTextValue())) + .failOn(FieldPersist._textValue).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{FieldPersist._textValue}, LocaleContextHolder.getLocale())), + this.spec() + .iff(()-> !this.isNull(item.getTextListValue()) && (fieldType.equals(FieldType.INTERNAL_ENTRIES_DMPS) || fieldType.equals(FieldType.INTERNAL_ENTRIES_DESCRIPTIONS))) + .must(() -> item.getTextListValue().stream().allMatch(this::isUUID)) + .failOn(FieldPersist._textListValue).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{FieldPersist._textListValue}, LocaleContextHolder.getLocale())), + this.navSpec() + .iff(() -> FieldType.isReferenceType(fieldType) && !this.isListNullOrEmpty(item.getReferences())) + .on(FieldPersist._references) + .over(item.getReferences()) + .using((itm) -> this.validatorFactory.validator(ReferencePersist.ReferencePersistValidator.class)), + this.refSpec() + .iff(() -> FieldType.isExternalIdentifierType(fieldType) && !this.isNull(item.getExternalIdentifier())) + .on(FieldPersist._externalIdentifier) + .over(item.getExternalIdentifier()) + .using(() -> this.validatorFactory.validator(ExternalIdentifierPersist.PersistValidator.class)) ); } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/datasetwizard/Rule.java b/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/datasetwizard/Rule.java index 99ad74094..797615ece 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/datasetwizard/Rule.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/publicapi/datasetwizard/Rule.java @@ -42,7 +42,11 @@ public class Rule { public Rule fromDefinitionRule(RuleEntity rule) { this.targetField = rule.getTarget(); - this.requiredValue = rule.getValue(); + //TODO + if (rule.getTextValue() != null && !rule.getTextListValue().isEmpty()) this.requiredValue = rule.getTextValue(); + else if (rule.getDateValue() != null) this.requiredValue = rule.getDateValue().toString(); + else if (rule.getTextListValue() != null) this.requiredValue = String.join(", ", rule.getTextListValue()); + else if (rule.getExternalIdentifier() != null) this.requiredValue = rule.getExternalIdentifier().getIdentifier(); return this; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java index 5a8db280d..eaaddd93e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java @@ -11,18 +11,16 @@ import eu.eudat.commons.scope.tenant.TenantScope; import eu.eudat.commons.scope.user.UserScope; import eu.eudat.commons.types.descriptiontemplate.*; import eu.eudat.commons.types.descriptiontemplate.fielddata.BaseFieldDataEntity; +import eu.eudat.commons.types.descriptiontemplate.fielddata.ReferenceTypeDataEntity; import eu.eudat.commons.types.descriptiontemplate.importexport.*; import eu.eudat.commons.types.notification.*; import eu.eudat.configurations.notification.NotificationProperties; import eu.eudat.convention.ConventionService; -import eu.eudat.data.DescriptionTemplateEntity; -import eu.eudat.data.UserDescriptionTemplateEntity; -import eu.eudat.data.UserEntity; +import eu.eudat.data.*; import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEvent; import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEventHandler; -import eu.eudat.model.DescriptionTemplate; -import eu.eudat.model.UserContactInfo; +import eu.eudat.model.*; import eu.eudat.model.builder.DescriptionTemplateBuilder; import eu.eudat.model.deleter.DescriptionTemplateDeleter; import eu.eudat.model.deleter.UserDescriptionTemplateDeleter; @@ -30,14 +28,10 @@ import eu.eudat.model.descriptiontemplatedefinition.Definition; import eu.eudat.model.descriptiontemplatedefinition.Field; import eu.eudat.model.descriptiontemplatedefinition.Page; import eu.eudat.model.descriptiontemplatedefinition.Section; -import eu.eudat.model.persist.DescriptionTemplatePersist; -import eu.eudat.model.persist.NewVersionDescriptionTemplatePersist; -import eu.eudat.model.persist.UserDescriptionTemplatePersist; +import eu.eudat.model.persist.*; import eu.eudat.model.persist.descriptiontemplatedefinition.*; import eu.eudat.model.persist.descriptiontemplatedefinition.fielddata.BaseFieldDataPersist; -import eu.eudat.query.DescriptionTemplateQuery; -import eu.eudat.query.UserContactInfoQuery; -import eu.eudat.query.UserDescriptionTemplateQuery; +import eu.eudat.query.*; import eu.eudat.service.fielddatahelper.FieldDataHelperService; import eu.eudat.service.fielddatahelper.FieldDataHelperServiceProvider; import eu.eudat.service.responseutils.ResponseUtilsService; @@ -68,6 +62,7 @@ import org.springframework.stereotype.Service; import org.xml.sax.SAXException; import javax.management.InvalidApplicationException; +import javax.ws.rs.NotSupportedException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import java.io.IOException; @@ -76,6 +71,7 @@ import java.time.Instant; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -393,7 +389,7 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic if (!this.conventionService.isListNullOrEmpty(persist.getVisibilityRules())) { data.setVisibilityRules(new ArrayList<>()); for (RulePersist fieldPersist : persist.getVisibilityRules()) { - data.getVisibilityRules().add(this.buildRuleEntity(fieldPersist)); + data.getVisibilityRules().add(this.buildRuleEntity(fieldPersist, data)); } } return data; @@ -405,13 +401,110 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic return this.fieldDataHelperServiceProvider.get(persist.getFieldType()).applyPersist(persist); } - private @NotNull RuleEntity buildRuleEntity(RulePersist persist) { + private @NotNull RuleEntity buildRuleEntity(RulePersist persist, FieldEntity fieldEntity){ + FieldType fieldType = fieldEntity != null && fieldEntity.getData() != null ? fieldEntity.getData().getFieldType() : FieldType.FREE_TEXT; RuleEntity data = new RuleEntity(); - if (persist == null) - return data; - + if (persist == null) return data; data.setTarget(persist.getTarget()); - data.setValue(persist.getValue()); + + if (FieldType.isTextType(fieldType)) { + if (FieldType.UPLOAD.equals(fieldType) && !this.conventionService.isNullOrEmpty(persist.getTextValue())){ + throw new NotSupportedException("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())){ + List ids = persist.getTextListValue().stream().map(UUID::fromString).toList(); + Set existingIds = this.queryFactory.query(DmpQuery.class).ids(ids).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(Dmp._id)).stream().map(DmpEntity::getId).collect(Collectors.toSet()); + for (UUID id : ids){ + if (!existingIds.contains(id)) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale())); + } + } if (FieldType.INTERNAL_ENTRIES_DESCRIPTIONS.equals(fieldType) && !this.conventionService.isListNullOrEmpty(persist.getTextListValue())){ + List ids = persist.getTextListValue().stream().map(UUID::fromString).toList(); + Set existingIds = this.queryFactory.query(DescriptionQuery.class).ids(ids).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(Description._id)).stream().map(DescriptionEntity::getId).collect(Collectors.toSet()); + for (UUID id : ids){ + if (!existingIds.contains(id)) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Description.class.getSimpleName()}, LocaleContextHolder.getLocale())); + } + } + data.setTextListValue(persist.getTextListValue()); + } + else if (FieldType.isReferenceType(fieldType) ) { + List referenceIds = this.patchAndSaveReferences(persist.getReferences(), fieldEntity); + if (!referenceIds.isEmpty()) data.setTextListValue(referenceIds.stream().map(UUID::toString).toList()); + } + else if (FieldType.isDateType(fieldType)) data.setDateValue(persist.getDateValue()); + else if (FieldType.isExternalIdentifierType(fieldType) && persist.getExternalIdentifier() != null) data.setExternalIdentifier(this.buildExternalIdentifierEntity(persist.getExternalIdentifier())); + + return data; + } + private @NotNull ExternalIdentifierEntity buildExternalIdentifierEntity(ExternalIdentifierPersist persist){ + ExternalIdentifierEntity data = new ExternalIdentifierEntity(); + if (persist == null) return data; + + data.setIdentifier(persist.getIdentifier()); + data.setType(persist.getType()); + return data; + } + + private List patchAndSaveReferences(List models, FieldEntity fieldEntity) { + if (models == null) models = new ArrayList<>(); + + List referenceIds = new ArrayList<>(); + + for (ReferencePersist model : models) { + ReferenceEntity data = null; + if (this.conventionService.isValidGuid(model.getId())){ + data = this.entityManager.find(ReferenceEntity.class, model.getId()); + if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), Reference.class.getSimpleName()}, LocaleContextHolder.getLocale())); + } else { + ReferenceTypeDataEntity referenceTypeDataEntity = ((ReferenceTypeDataEntity)fieldEntity.getData()); + data = this.queryFactory.query(ReferenceQuery.class).sourceTypes(model.getSourceType()).typeIds(referenceTypeDataEntity.getReferenceTypeId()).sources(model.getSource()).isActive(IsActive.Active).references(model.getReference()).first(); + if (data == null){ + data = new ReferenceEntity(); + data.setId(UUID.randomUUID()); + data.setIsActive(IsActive.Active); + data.setCreatedAt(Instant.now()); + data.setTypeId(referenceTypeDataEntity.getReferenceTypeId()); + + data.setDefinition(this.xmlHandlingService.toXmlSafe(this.buildReferenceDefinitionEntity(model.getDefinition()))); + data.setUpdatedAt(Instant.now()); + data.setReference(model.getReference()); + data.setAbbreviation(model.getAbbreviation()); + data.setSource(model.getSource()); + data.setSourceType(model.getSourceType()); + this.entityManager.persist(data); + } + } + referenceIds.add(data.getId()); + } + this.entityManager.flush(); + + return referenceIds; + } + + private @NotNull eu.eudat.commons.types.reference.DefinitionEntity buildReferenceDefinitionEntity(eu.eudat.model.persist.referencedefinition.DefinitionPersist persist){ + eu.eudat.commons.types.reference.DefinitionEntity data = new eu.eudat.commons.types.reference.DefinitionEntity(); + if (persist == null) return data; + if (!this.conventionService.isListNullOrEmpty(persist.getFields())){ + data.setFields(new ArrayList<>()); + for (eu.eudat.model.persist.referencedefinition.FieldPersist fieldPersist: persist.getFields()) { + data.getFields().add(this.buildRefernceFieldEntity(fieldPersist)); + } + } + + return data; + } + + private @NotNull eu.eudat.commons.types.reference.FieldEntity buildRefernceFieldEntity(eu.eudat.model.persist.referencedefinition.FieldPersist persist){ + eu.eudat.commons.types.reference.FieldEntity data = new eu.eudat.commons.types.reference.FieldEntity(); + if (persist == null) return data; + + data.setCode(persist.getCode()); + data.setDataType(persist.getDataType()); + data.setCode(persist.getCode()); + return data; } @@ -750,7 +843,10 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic public RulePersist toRuleModel(RuleImportExport importExport) { RulePersist ruleEntity = new RulePersist(); ruleEntity.setTarget(importExport.getTarget()); - ruleEntity.setValue(importExport.getValue()); + ruleEntity.setDateValue(importExport.getDateValue()); + //ruleEntity.setReferences(importExport.get()); //TODO + ruleEntity.setTextValue(importExport.getTextValue()); + ruleEntity.setTextListValue(importExport.getTextListValue()); return ruleEntity; } @@ -885,7 +981,14 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic private RuleImportExport toRuleModel(RuleEntity entity) { RuleImportExport xml = new RuleImportExport(); xml.setTarget(entity.getTarget()); - xml.setValue(entity.getValue()); + xml.setDateValue(entity.getDateValue()); + xml.setTextListValue(entity.getTextListValue()); + xml.setTextValue(entity.getTextValue()); + if (entity.getExternalIdentifier() != null){ + xml.setExternalIdentifier(new ExternalIdentifierImportExport()); + xml.getExternalIdentifier().setIdentifier(entity.getExternalIdentifier().getIdentifier()); + xml.getExternalIdentifier().setType(entity.getExternalIdentifier().getType()); + } return xml; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/visibility/ExternalIdentifier.java b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/ExternalIdentifier.java new file mode 100644 index 000000000..c42866c95 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/ExternalIdentifier.java @@ -0,0 +1,27 @@ +package eu.eudat.service.visibility; + +import eu.eudat.commons.types.description.ExternalIdentifierEntity; +import eu.eudat.model.persist.descriptionproperties.ExternalIdentifierPersist; + +public class ExternalIdentifier { + private final String identifier; + private final String type; + + public String getIdentifier() { + return identifier; + } + + public String getType() { + return type; + } + + public ExternalIdentifier(ExternalIdentifierPersist persist){ + this.identifier = persist.getIdentifier(); + this.type = persist.getType(); + } + + public ExternalIdentifier(ExternalIdentifierEntity entity){ + this.identifier = entity.getIdentifier(); + this.type = entity.getType(); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/visibility/Field.java b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/Field.java new file mode 100644 index 000000000..7323650cb --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/Field.java @@ -0,0 +1,63 @@ +package eu.eudat.service.visibility; + +import eu.eudat.commons.types.description.FieldEntity; +import eu.eudat.model.persist.descriptionproperties.FieldPersist; + +import java.time.Instant; +import java.util.List; + +public class Field { + + private final String textValue; + + private final List textListValue; + + private final Instant dateValue; + + private final ExternalIdentifier externalIdentifier; + + public String getTextValue() { + return textValue; + } + + + public List getTextListValue() { + return textListValue; + } + + + public Instant getDateValue() { + return dateValue; + } + + + public ExternalIdentifier getExternalIdentifier() { + return externalIdentifier; + } + + + public Field(FieldPersist persist){ + List tempTextListValue; + this.textValue = persist.getTextValue(); + this.dateValue = persist.getDateValue(); + tempTextListValue = persist.getTextListValue(); + if (persist.getExternalIdentifier() != null) this.externalIdentifier = new ExternalIdentifier(persist.getExternalIdentifier()); + else this.externalIdentifier = null; + if (persist.getReferences() != null && !persist.getReferences().isEmpty()){ + tempTextListValue = persist.getReferences().stream().filter(x-> x.getId() != null).map(x-> x.getId().toString()).toList(); + } + this.textListValue = tempTextListValue; + } + + + public Field(FieldEntity entity){ + this.textValue = entity.getTextValue(); + this.dateValue = entity.getDateValue(); + this.textListValue = entity.getTextListValue(); + if (entity.getExternalIdentifier() != null) this.externalIdentifier = new ExternalIdentifier(entity.getExternalIdentifier()); + else this.externalIdentifier = null; + } + +} + + diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/visibility/FieldKey.java b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/FieldKey.java new file mode 100644 index 000000000..f75bca2f6 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/FieldKey.java @@ -0,0 +1,40 @@ +package eu.eudat.service.visibility; + +import java.util.Objects; + +public class FieldKey { + private final String fieldId; + private final Integer ordinal; + private final int hashCode; + + + public FieldKey(String fieldId, Integer ordinal) { + this.fieldId = fieldId; + this.ordinal = ordinal; + hashCode = Objects.hash(this.fieldId, this.ordinal); + } + + public Integer getOrdinal() { + return ordinal; + } + + public String getFieldId() { + return fieldId; + } + + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + FieldKey that = (FieldKey) o; + return Objects.equals(ordinal, that.getOrdinal()) && Objects.equals(fieldId, that.getFieldId()); + } + + @Override + public int hashCode() { + return this.hashCode; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/visibility/PropertyDefinition.java b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/PropertyDefinition.java new file mode 100644 index 000000000..cf74625d9 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/PropertyDefinition.java @@ -0,0 +1,34 @@ +package eu.eudat.service.visibility; + +import eu.eudat.commons.types.description.PropertyDefinitionEntity; +import eu.eudat.commons.types.description.PropertyDefinitionFieldSetEntity; +import eu.eudat.model.persist.descriptionproperties.PropertyDefinitionFieldSetPersist; +import eu.eudat.model.persist.descriptionproperties.PropertyDefinitionPersist; + +import java.util.HashMap; +import java.util.Map; + +public class PropertyDefinition { + + private final Map fieldSets; + + public Map getFieldSets() { + return fieldSets; + } + + public PropertyDefinition(PropertyDefinitionPersist persist){ + this.fieldSets = new HashMap<>(); + if (persist == null || persist.getFieldSets() == null || persist.getFieldSets().isEmpty()) return; + for (Map.Entry item : persist.getFieldSets().entrySet()){ + this.fieldSets.put(item.getKey(), new PropertyDefinitionFieldSet(item.getValue())); + } + } + + public PropertyDefinition(PropertyDefinitionEntity entity){ + this.fieldSets = new HashMap<>(); + if (entity == null || entity.getFieldSets() == null || entity.getFieldSets().isEmpty()) return; + for (Map.Entry item : entity.getFieldSets().entrySet()){ + this.fieldSets.put(item.getKey(), new PropertyDefinitionFieldSet(item.getValue())); + } + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/visibility/PropertyDefinitionFieldSet.java b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/PropertyDefinitionFieldSet.java new file mode 100644 index 000000000..8bf1cc7d8 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/PropertyDefinitionFieldSet.java @@ -0,0 +1,42 @@ +package eu.eudat.service.visibility; + +import eu.eudat.commons.types.description.PropertyDefinitionFieldSetEntity; +import eu.eudat.commons.types.description.PropertyDefinitionFieldSetItemEntity; +import eu.eudat.model.persist.descriptionproperties.PropertyDefinitionFieldSetItemPersist; +import eu.eudat.model.persist.descriptionproperties.PropertyDefinitionFieldSetPersist; + +import java.util.ArrayList; +import java.util.List; + +public class PropertyDefinitionFieldSet { + + private final List items; + + public List getItems() { + return items; + } + + public PropertyDefinitionFieldSet(PropertyDefinitionFieldSetPersist persist){ + if (persist == null || persist.getItems() == null || persist.getItems().isEmpty()) { + this.items = null; + return; + } + this.items = new ArrayList<>(); + for (PropertyDefinitionFieldSetItemPersist item : persist.getItems()){ + this.items.add(new PropertyDefinitionFieldSetItem(item)); + } + } + + public PropertyDefinitionFieldSet(PropertyDefinitionFieldSetEntity entity){ + if (entity == null || entity.getItems() == null || entity.getItems().isEmpty()) { + this.items = null; + return; + } + this.items = new ArrayList<>(); + for (PropertyDefinitionFieldSetItemEntity item : entity.getItems()){ + this.items.add(new PropertyDefinitionFieldSetItem(item)); + } + } +} + + diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/visibility/PropertyDefinitionFieldSetItem.java b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/PropertyDefinitionFieldSetItem.java new file mode 100644 index 000000000..aa97829a8 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/PropertyDefinitionFieldSetItem.java @@ -0,0 +1,54 @@ +package eu.eudat.service.visibility; + +import eu.eudat.commons.types.description.FieldEntity; +import eu.eudat.commons.types.description.PropertyDefinitionFieldSetItemEntity; +import eu.eudat.model.persist.descriptionproperties.FieldPersist; +import eu.eudat.model.persist.descriptionproperties.PropertyDefinitionFieldSetItemPersist; + +import java.util.HashMap; +import java.util.Map; + +public class PropertyDefinitionFieldSetItem { + + private final Map fields; + + private final Integer ordinal; + + public Map getFields() { + return fields; + } + + + public Integer getOrdinal() { + return ordinal; + } + + + public PropertyDefinitionFieldSetItem(PropertyDefinitionFieldSetItemPersist persist){ + this.ordinal = persist.getOrdinal(); + + if (persist.getFields() == null || persist.getFields().isEmpty()) { + this.fields = null; + return; + } + this.fields = new HashMap<>(); + for (Map.Entry item : persist.getFields().entrySet()){ + this.fields.put(item.getKey(), new Field(item.getValue())); + } + } + + public PropertyDefinitionFieldSetItem(PropertyDefinitionFieldSetItemEntity entity){ + this.ordinal = entity.getOrdinal(); + + if (entity.getFields() == null || entity.getFields().isEmpty()) { + this.fields = null; + return; + } + this.fields = new HashMap<>(); + for (Map.Entry item : entity.getFields().entrySet()){ + this.fields.put(item.getKey(), new Field(item.getValue())); + } + } +} + + diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/visibility/RuleWithTarget.java b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/RuleWithTarget.java new file mode 100644 index 000000000..78f24799d --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/RuleWithTarget.java @@ -0,0 +1,49 @@ +package eu.eudat.service.visibility; + +import eu.eudat.commons.types.descriptiontemplate.FieldEntity; +import eu.eudat.commons.types.descriptiontemplate.RuleEntity; + +import java.time.Instant; +import java.util.List; + +public class RuleWithTarget{ + private final String target; + private final String source; + private final String textValue; + private final List textListValue; + private final Instant dateValue; + private final FieldEntity fieldEntity; + + public RuleWithTarget(String source, RuleEntity rule, FieldEntity fieldEntity) { + this.target = rule.getTarget(); + this.source = source; + this.fieldEntity = fieldEntity; + this.textValue = rule.getTextValue(); + this.textListValue = rule.getTextListValue(); + this.dateValue = rule.getDateValue(); + } + + public String getTarget() { + return target; + } + + public String getSource() { + return source; + } + + public String getTextValue() { + return textValue; + } + + public List getTextListValue() { + return textListValue; + } + + public Instant getDateValue() { + return dateValue; + } + + public FieldEntity getFieldEntity() { + return fieldEntity; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/visibility/VisibilityService.java b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/VisibilityService.java new file mode 100644 index 000000000..81830cecd --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/VisibilityService.java @@ -0,0 +1,5 @@ +package eu.eudat.service.visibility; + +public interface VisibilityService { + boolean isVisible(String id, Integer ordinal); +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/visibility/VisibilityServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/VisibilityServiceImpl.java new file mode 100644 index 000000000..5267c14e3 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/visibility/VisibilityServiceImpl.java @@ -0,0 +1,373 @@ +package eu.eudat.service.visibility; + +import eu.eudat.commons.types.description.PropertyDefinitionEntity; +import eu.eudat.commons.types.descriptiontemplate.*; +import eu.eudat.model.persist.descriptionproperties.PropertyDefinitionPersist; + +import javax.ws.rs.NotSupportedException; +import java.util.*; + +public class VisibilityServiceImpl implements VisibilityService { + + private final DefinitionEntity definition; + private final PropertyDefinition propertyDefinition; + + private Map> rulesBySources; + private Map visibility; + + public VisibilityServiceImpl(DefinitionEntity definition, PropertyDefinitionPersist propertyDefinition) { + this.definition = definition; + this.propertyDefinition = new PropertyDefinition(propertyDefinition); + } + + public VisibilityServiceImpl(DefinitionEntity definition, PropertyDefinitionEntity propertyDefinition) { + this.definition = definition; + this.propertyDefinition = new PropertyDefinition(propertyDefinition); + } + + private void initRules(){ + if (this.rulesBySources == null) return; + rulesBySources = new HashMap<>(); + for (FieldEntity fieldEntity : this.definition.getAllField()){ + if (fieldEntity.getVisibilityRules() != null && !fieldEntity.getVisibilityRules().isEmpty()) { + for (RuleEntity rule : fieldEntity.getVisibilityRules()){ + if (!rulesBySources.containsKey(fieldEntity.getId())) rulesBySources.put(fieldEntity.getId(), new ArrayList<>()); + RuleWithTarget ruleWithTarget = new RuleWithTarget(fieldEntity.getId(), rule, fieldEntity); + rulesBySources.get(fieldEntity.getId()).add(ruleWithTarget); + } + } + } + } + + @Override + public boolean isVisible(String id, Integer ordinal) { + this.calculateVisibility(); + FieldKey fieldKey = new FieldKey(id, ordinal); + return this.visibility.getOrDefault(fieldKey, false); + } + + private void calculateVisibility(){ + if (visibility != null) return; + + this.initRules(); + this.buildTargetVisibility(); + this.expandVisibilityToChildren(); + this.setDefaultVisibilityForNotCaclucted(); + this.hideParentIfAllChildrenAreHidden(); + } + + private void buildTargetVisibility(){ + visibility = new HashMap<>(); + for (Map.Entry> ruleForSource : rulesBySources.entrySet()){ + for (RuleWithTarget rule : ruleForSource.getValue()){ + if (propertyDefinition.getFieldSets() != null && !propertyDefinition.getFieldSets().isEmpty()){ + for (PropertyDefinitionFieldSet propertyDefinitionFieldSet: propertyDefinition.getFieldSets().values()) { + if (propertyDefinitionFieldSet.getItems() != null && !propertyDefinitionFieldSet.getItems().isEmpty()) { + for (PropertyDefinitionFieldSetItem definitionFieldSetItem : propertyDefinitionFieldSet.getItems()) { + if (definitionFieldSetItem.getFields() != null && !definitionFieldSetItem.getFields().isEmpty()) { + for (String key : definitionFieldSetItem.getFields().keySet()) { + if (rule.getSource().equals(key)){ + Field field = definitionFieldSetItem.getFields().get(key); + + if (definitionFieldSetItem.getFields().containsKey(rule.getTarget())){ //Rule applies only for current multiple item + FieldKey fieldKey = new FieldKey(rule.getTarget(), definitionFieldSetItem.getOrdinal()); + boolean currentState = this.visibility.getOrDefault(fieldKey, false); + this.visibility.put(fieldKey, currentState || ruleIsTrue(rule, field)); + } else if (!this.definition.getFieldById(rule.getTarget()).isEmpty() || !this.definition.getFieldSetById(rule.getTarget()).isEmpty()) { //Rule applies to different fieldset, so we apply for all multiple items + List ordinals = this.getKeyOrdinals(rule.getTarget()); + for (Integer ordinal : ordinals){ + FieldKey fieldKey = new FieldKey(rule.getTarget(), ordinal); + boolean currentState = this.visibility.getOrDefault(fieldKey, false); + this.visibility.put(fieldKey, currentState || ruleIsTrue(rule, field)); + } + } else { + FieldKey fieldKey = new FieldKey(rule.getTarget(), null); //Ordinal is null if target not on field + boolean currentState = this.visibility.getOrDefault(fieldKey, false); + this.visibility.put(fieldKey, currentState || ruleIsTrue(rule, field)); + } + } + } + } + } + } + } + } + } + } + } + + private List getKeyOrdinals(String key){ + if (propertyDefinition.getFieldSets() != null && !propertyDefinition.getFieldSets().isEmpty()){ + for (Map.Entry propertyDefinitionFieldSet: propertyDefinition.getFieldSets().entrySet()) { + if (propertyDefinitionFieldSet.getKey().equals(key)) return propertyDefinitionFieldSet.getValue().getItems().stream().map(PropertyDefinitionFieldSetItem::getOrdinal).toList(); + + if (propertyDefinitionFieldSet.getValue() != null && propertyDefinitionFieldSet.getValue().getItems() != null && !propertyDefinitionFieldSet.getValue().getItems().isEmpty()) { + for (PropertyDefinitionFieldSetItem definitionFieldSetItem : propertyDefinitionFieldSet.getValue().getItems()) { + if (definitionFieldSetItem.getFields() != null && !definitionFieldSetItem.getFields().isEmpty()) { + for (String fieldKey : definitionFieldSetItem.getFields().keySet()) { + if (fieldKey.equals(key)) return propertyDefinitionFieldSet.getValue().getItems().stream().map(PropertyDefinitionFieldSetItem::getOrdinal).toList(); + } + } + } + } + } + } + return new ArrayList<>(); + } + + private void expandVisibilityToChildren(){ + if (this.definition.getPages() == null) return; + for (PageEntity pageEntity : this.definition.getPages()){ + FieldKey fieldKey = new FieldKey(pageEntity.getId(), null); + Boolean currentValue = this.visibility.getOrDefault(fieldKey, null); + this.expandPageVisibility(pageEntity, currentValue); + } + } + + private void expandPageVisibility(PageEntity pageEntity, Boolean parentVisibility){ + if (pageEntity.getSections() == null) return; + for (SectionEntity sectionEntity : pageEntity.getSections()){ + FieldKey fieldKey = new FieldKey(sectionEntity.getId(), null); + Boolean currentValue = this.visibility.getOrDefault(fieldKey, null); + if (currentValue != null){ + if (parentVisibility != null && !parentVisibility) { //Parent is hidden so all childs should be hidden + this.visibility.put(fieldKey, false); + this.expandSectionVisibility(sectionEntity, currentValue); + } else { + this.expandSectionVisibility(sectionEntity, currentValue); + } + } else { + if (parentVisibility != null) this.visibility.put(fieldKey, parentVisibility); + this.expandSectionVisibility(sectionEntity, parentVisibility); + } + } + } + private void expandSectionVisibility(SectionEntity sectionEntity, Boolean parentVisibility){ + if (sectionEntity.getSections() != null) { + for (SectionEntity subSectionEntity : sectionEntity.getSections()) { + FieldKey fieldKey = new FieldKey(subSectionEntity.getId(), null); + Boolean currentValue = this.visibility.getOrDefault(fieldKey, null); + if (currentValue != null){ + if (parentVisibility != null && !parentVisibility) { //Parent is hidden so all childs should be hidden + this.visibility.put(fieldKey, false); + this.expandSectionVisibility(subSectionEntity, currentValue); + } else { + this.expandSectionVisibility(subSectionEntity, currentValue); + } + } else { + if (parentVisibility != null) this.visibility.put(fieldKey, parentVisibility); + this.expandSectionVisibility(subSectionEntity, parentVisibility); + } + } + } + if (sectionEntity.getFieldSets() != null) { + for (FieldSetEntity fieldSetEntity : sectionEntity.getFieldSets()) { + if (propertyDefinition.getFieldSets() != null && !propertyDefinition.getFieldSets().isEmpty()){ + PropertyDefinitionFieldSet propertyDefinitionFieldSet = propertyDefinition.getFieldSets().getOrDefault(fieldSetEntity.getId(), null); + if (propertyDefinitionFieldSet != null && propertyDefinitionFieldSet.getItems() != null && !propertyDefinitionFieldSet.getItems().isEmpty()) { + for (PropertyDefinitionFieldSetItem definitionFieldSetItem : propertyDefinitionFieldSet.getItems()) { + FieldKey fieldKey = new FieldKey(fieldSetEntity.getId(), definitionFieldSetItem.getOrdinal()); + Boolean currentValue = this.visibility.getOrDefault(fieldKey, null); + if (currentValue != null){ + if (parentVisibility != null && !parentVisibility) { //Parent is hidden so all childs should be hidden + this.visibility.put(fieldKey, false); + this.expandFieldSetVisibility(fieldSetEntity, currentValue, definitionFieldSetItem.getOrdinal()); + } else { + this.expandFieldSetVisibility(fieldSetEntity, currentValue, definitionFieldSetItem.getOrdinal()); + } + } else { + if (parentVisibility != null) this.visibility.put(fieldKey, parentVisibility); + this.expandFieldSetVisibility(fieldSetEntity, parentVisibility, definitionFieldSetItem.getOrdinal()); + } + } + } + } + } + } + } + + private void expandFieldSetVisibility(FieldSetEntity fieldSetEntity, Boolean parentVisibility, Integer ordinal){ + if (fieldSetEntity.getFields() != null) { + for (FieldEntity fieldEntity : fieldSetEntity.getFields()) { + FieldKey fieldKey = new FieldKey(fieldEntity.getId(), ordinal); + Boolean currentValue = this.visibility.getOrDefault(fieldKey, null); + if (currentValue != null){ + if (parentVisibility != null && !parentVisibility) { //Parent is hidden so all childs should be hidden + this.visibility.put(fieldKey, false); + } + } else if (parentVisibility != null){ + this.visibility.put(fieldKey, parentVisibility); + } + } + } + } + + + private void setDefaultVisibilityForNotCaclucted(){ + if (this.definition.getPages() == null) return; + for (PageEntity pageEntity : this.definition.getPages()){ + FieldKey fieldKey = new FieldKey(pageEntity.getId(), null); + Boolean currentValue = this.visibility.getOrDefault(fieldKey, null); + if (currentValue == null) this.visibility.put(fieldKey, true); + this.setDefaultPageVisibility(pageEntity); + } + } + + private void setDefaultPageVisibility(PageEntity pageEntity){ + if (pageEntity.getSections() == null) return; + for (SectionEntity sectionEntity : pageEntity.getSections()){ + FieldKey fieldKey = new FieldKey(sectionEntity.getId(), null); + Boolean currentValue = this.visibility.getOrDefault(fieldKey, null); + if (currentValue == null){ + this.visibility.put(fieldKey, true); + this.setDefaultSectionVisibility(sectionEntity); + } + } + } + + private void setDefaultSectionVisibility(SectionEntity sectionEntity){ + if (sectionEntity.getSections() != null) { + for (SectionEntity subSectionEntity : sectionEntity.getSections()) { + FieldKey fieldKey = new FieldKey(subSectionEntity.getId(), null); + Boolean currentValue = this.visibility.getOrDefault(fieldKey, null); + if (currentValue == null){ + this.visibility.put(fieldKey, true); + this.setDefaultSectionVisibility(sectionEntity); + } + } + } + if (sectionEntity.getFieldSets() != null) { + for (FieldSetEntity fieldSetEntity : sectionEntity.getFieldSets()) { + if (propertyDefinition.getFieldSets() != null && !propertyDefinition.getFieldSets().isEmpty()){ + PropertyDefinitionFieldSet propertyDefinitionFieldSet = propertyDefinition.getFieldSets().getOrDefault(fieldSetEntity.getId(), null); + if (propertyDefinitionFieldSet != null && propertyDefinitionFieldSet.getItems() != null && !propertyDefinitionFieldSet.getItems().isEmpty()) { + for (PropertyDefinitionFieldSetItem definitionFieldSetItem : propertyDefinitionFieldSet.getItems()) { + FieldKey fieldKey = new FieldKey(fieldSetEntity.getId(), definitionFieldSetItem.getOrdinal()); + Boolean currentValue = this.visibility.getOrDefault(fieldKey, null); + if (currentValue == null){ + this.visibility.put(fieldKey, true); + this.setDefaultFieldSetVisibility(fieldSetEntity, definitionFieldSetItem.getOrdinal()); + } + } + } + } + } + } + } + + private void setDefaultFieldSetVisibility(FieldSetEntity fieldSetEntity, Integer ordinal){ + if (fieldSetEntity.getFields() != null) { + for (FieldEntity fieldEntity : fieldSetEntity.getFields()) { + FieldKey fieldKey = new FieldKey(fieldEntity.getId(), ordinal); + Boolean currentValue = this.visibility.getOrDefault(fieldKey, null); + if (currentValue == null){ + this.visibility.put(fieldKey, true); + } + } + } + } + + private void hideParentIfAllChildrenAreHidden(){ + if (this.definition.getPages() == null) return; + for (PageEntity pageEntity : this.definition.getPages()){ + FieldKey fieldKey = new FieldKey(pageEntity.getId(), null); + boolean isCurrentHidden = this.isHiddenPageVisibilityIfAllChildrenIsHidden(pageEntity); + if (this.visibility.getOrDefault(fieldKey, true) && isCurrentHidden){ + this.visibility.put(fieldKey, false); + } + } + } + + private boolean isHiddenPageVisibilityIfAllChildrenIsHidden(PageEntity pageEntity){ + boolean isHidden = true; + if (pageEntity.getSections() == null) return isHidden; + + for (SectionEntity sectionEntity : pageEntity.getSections()){ + FieldKey fieldKey = new FieldKey(sectionEntity.getId(), null); + boolean isCurrentHidden = this.isHiddenSectionIfAllChildrenIsHidden(sectionEntity); + if (this.visibility.getOrDefault(fieldKey, true) && isCurrentHidden){ + this.visibility.put(fieldKey, false); + } + isHidden = isHidden && isCurrentHidden; + } + return isHidden; + } + + private boolean isHiddenSectionIfAllChildrenIsHidden(SectionEntity sectionEntity){ + boolean isHidden = true; + if (sectionEntity.getSections() != null) { + for (SectionEntity subSectionEntity : sectionEntity.getSections()) { + FieldKey fieldKey = new FieldKey(subSectionEntity.getId(), null); + boolean isCurrentHidden = this.isHiddenSectionIfAllChildrenIsHidden(subSectionEntity); + if (this.visibility.getOrDefault(fieldKey, true) && isCurrentHidden){ + this.visibility.put(fieldKey, false); + } + isHidden = isHidden && isCurrentHidden; + } + } + if (sectionEntity.getFieldSets() != null) { + for (FieldSetEntity fieldSetEntity : sectionEntity.getFieldSets()) { + if (propertyDefinition.getFieldSets() != null && !propertyDefinition.getFieldSets().isEmpty()){ + PropertyDefinitionFieldSet propertyDefinitionFieldSet = propertyDefinition.getFieldSets().getOrDefault(fieldSetEntity.getId(), null); + if (propertyDefinitionFieldSet != null && propertyDefinitionFieldSet.getItems() != null && !propertyDefinitionFieldSet.getItems().isEmpty()) { + for (PropertyDefinitionFieldSetItem definitionFieldSetItem : propertyDefinitionFieldSet.getItems()) { + FieldKey fieldKey = new FieldKey(fieldSetEntity.getId(), definitionFieldSetItem.getOrdinal()); + boolean isCurrentHidden = this.isHiddenFieldSetIfAllChildrenIsHidden(fieldSetEntity, definitionFieldSetItem.getOrdinal()); + if (this.visibility.getOrDefault(fieldKey, true) && isCurrentHidden){ + this.visibility.put(fieldKey, false); + } + isHidden = isHidden && isCurrentHidden; + } + } + } + } + } + return isHidden; + } + + private boolean isHiddenFieldSetIfAllChildrenIsHidden(FieldSetEntity fieldSetEntity, Integer ordinal){ + boolean isHidden = true; + if (fieldSetEntity.getFields() != null) { + for (FieldEntity fieldEntity : fieldSetEntity.getFields()) { + FieldKey fieldKey = new FieldKey(fieldEntity.getId(), ordinal); + Boolean currentValue = this.visibility.getOrDefault(fieldKey, true); + isHidden = isHidden && !currentValue; + } + return isHidden; + } + return true; + } + + private boolean ruleIsTrue(RuleWithTarget rule, Field field){ + if (field != null){ + eu.eudat.commons.enums.FieldType fieldType = rule.getFieldEntity() != null && rule.getFieldEntity().getData() != null ? rule.getFieldEntity().getData().getFieldType() : eu.eudat.commons.enums.FieldType.FREE_TEXT; + if (eu.eudat.commons.enums.FieldType.isTextType(fieldType) && field.getTextValue() != null && !field.getTextValue().isBlank()) { + if (eu.eudat.commons.enums.FieldType.UPLOAD.equals(fieldType)){ + throw new NotSupportedException("Upload file rule not supported"); + } else { + return field.getTextValue().equals(rule.getTextValue()); + } + } + else if (eu.eudat.commons.enums.FieldType.isTextListType(fieldType) && field.getTextListValue() != null && !field.getTextListValue().isEmpty()) { + return rule.getTextListValue() != null && + new HashSet<>(field.getTextListValue()).containsAll(rule.getTextListValue()) && + new HashSet<>(rule.getTextListValue()).containsAll(field.getTextListValue()); + } + else if (eu.eudat.commons.enums.FieldType.isReferenceType(fieldType)) { + return rule.getTextListValue() != null && + new HashSet<>(field.getTextListValue()).containsAll(rule.getTextListValue()) && + new HashSet<>(rule.getTextListValue()).containsAll(field.getTextListValue()); + } + else if (eu.eudat.commons.enums.FieldType.isDateType(fieldType) && field.getDateValue() != null) return field.getDateValue().equals(rule.getDateValue()); + else if (eu.eudat.commons.enums.FieldType.isExternalIdentifierType(fieldType) && field.getExternalIdentifier() != null) { + throw new NotSupportedException("External identifier rule not supported"); + } + } + return false; + } + + + + +} + diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/publicapi/PublicDatasetsDescriptionDocumentation.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/publicapi/PublicDatasetsDescriptionDocumentation.java index 4522d2ae5..2e3cbed4d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/publicapi/PublicDatasetsDescriptionDocumentation.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/publicapi/PublicDatasetsDescriptionDocumentation.java @@ -192,7 +192,11 @@ public class PublicDatasetsDescriptionDocumentation { 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), - String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._visibilityRules, Rule._value), + String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._visibilityRules, Rule._dateValue), + String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._visibilityRules, Rule._textListValue), + String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._visibilityRules, Rule._textValue), + String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._visibilityRules, Rule._externalIdentifier), + String.join(".", Description._descriptionTemplate, DescriptionTemplate._definition, Definition._pages, Page._sections, Section._fieldSets, FieldSet._fields, Field._visibilityRules, Rule._references), Description._createdAt, Description._updatedAt, Description._finalizedAt